MSHTML HTMLHeadElementClass COM错误 [英] MSHTML HTMLHeadElementClass COM Error

查看:175
本文介绍了MSHTML HTMLHeadElementClass COM错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在与MS HTML工作插入JavaScript代码到网站。

I'm currently working with MS HTML to insert a JavaScript code into websites.

我作出Microsoft HTML对象库和类型的代码的参考。

I made a reference to Microsoft HTML Object Library and types this code.

IHTMLDocument2 doc = BrowserHost.Document as HTMLDocumentClass;
IHTMLElement head = (IHTMLElement)
      ((IHTMLElementCollection)doc.all.tags("head")).item(null, 0);
IHTMLScriptElement scriptObject = 
      (IHTMLScriptElement)doc.createElement("script");
scriptObject.type = @"text/javascript";
scriptObject.text = TTS.TTSWebFactory.GetJavascript();
((HTMLHeadElementClass)head).appendChild((IHTMLDOMNode)scriptObject);



我得到剧本的最后一行的错误,这就是消息。

I get an error on the last line of the script, this is the message.

Unable to cast COM object of type 'System._ComObject' to class type 
'mshtml.HTMLHeadElementClass'. COM components that enter the CLR and do not 
support IProvideClassInfo or that do not havae any iterop assembly registered 
will be wrapped in the _ComObject type. Instances of this type cannot be cast 
to any other class; however they can be cast to interfaces as long as the 
underlying COM component supports QueryInterface calls for the IID of the 
interface

$投射到接口b
$ b

我没有用COM太多的经验,并保持最后一行诠释他的代码,任何人可以帮助我理解这意味着什么,我该如何解决这个问题是非常重要的?

I don't have much experience with COM and it is important to keep the last line int he code, can any one help me understand what this means and how i solve it ?

推荐答案

有与你走出类型库类似的MSHTML.tlb的互操作类的一个非常严重的问题。类型库导入从类型库中的coclass定义生成合成.NET类。可以从它们的类型名称识别它们,它们在类结束,一个接口类型的名称开始。这意味着它们是有帮助的,让你对待COM组件类,仿佛它是一个.NET类。

There is a very serious problem with the interop classes that you get out of a type library like mshtml.tlb. The type library importer generates synthetic .NET classes from the coclass definitions in the type library. You can recognize them from their type names, they end in "Class" and start with the name of an interface type. They are meant to be helpful, allowing you to treat the COM coclass as though it was a .NET class.

然而,他们造成非常严重的版本问题。当我使用OLEView.exe这类看看我的MSHTML.tlb的机器上,然后我看到这个定义为HTMLHeadElement组件类:

They however cause a very serious versioning problem. When I use oleview.exe to look at mshtml.tlb on my machine then I see this definition for the HTMLHeadElement coclass:

[
  uuid(3050F493-98B5-11CF-BB82-00AA00BDCE0B),
  noncreatable
]
coclass HTMLHeadElement {
    [default] dispinterface DispHTMLHeadElement;
    [default, source] dispinterface HTMLElementEvents;
    [source] dispinterface HTMLElementEvents2;
    interface IHTMLElement;
    interface IHTMLElement2;
    interface IHTMLElement3;
    interface IHTMLElement4;
    interface IHTMLUniqueName;
    interface IHTMLDOMNode;
    interface IHTMLDOMNode2;
    interface IHTMLElement5;
    interface IHTMLDOMConstructor;
    interface IHTMLHeadElement;
    interface IHTMLHeadElement2;
};



在源代码当我右键单击mshtml.HtmlHeadElementClass并选择转到定义,然后我看到这个

When I right-click mshtml.HtmlHeadElementClass in the source code and select Go To Definition then I see this:

public class HTMLHeadElementClass : DispHTMLHeadElement, HTMLHeadElement, 
   HTMLElementEvents_Event, IHTMLElement, IHTMLElement2, IHTMLElement3, 
   IHTMLElement4, IHTMLUniqueName, IHTMLDOMNode, IHTMLDOMNode2, 
   IHTMLHeadElement, IHTMLElementEvents2_Event {
   // Lots of members
   //...
}

请注意两者之间的失配。我从OLEVIEW得到的一个人的额外的的接口,IHtmlElement5和IHtmlHeadElement2。原因很简单解释,我有我的机器上安装IE9。互操作的定义来自于MSHTML PIA。这是一个的的版本,大概可以追溯到IE7。

Note the mismatch between the two. The one I got from Oleview has extra interfaces, IHtmlElement5 and IHtmlHeadElement2. The reason is simple to explain, I have IE9 installed on my machine. The interop definition came from the mshtml PIA. Which is an old version, probably dating back to IE7.

可怕的问题是,新的IHtmlElement5接口得到的插入到继承列表。这是一个非常严重的错误,至少就.NET代码去。这不要紧,在所有纯COM代码,那永远只能适用于接口,并询问与的QueryInterface接口指针的组件类。但是,它的致命到.NET包装类,所有的过去IHTMLDOMNode2的方法有错误的偏移量。所以,如果你调用IHTMLHeadElement.appendChild方法,那么你最终会调用在错误方式。

The horrifying problem is that new IHtmlElement5 interface got inserted into the inheritance list. This was a very serious mistake, at least as far as .NET code goes. It doesn't matter at all to pure COM code, that only ever works with interfaces and asks the coclass for an interface pointer with QueryInterface. It is however fatal to the .NET wrapper class, all of the methods past IHTMLDOMNode2 have the wrong offset. So if you call the IHTMLHeadElement.appendChild method then you'll end up calling the wrong method.

这是一个无法解决的问题。您可以卸载PIA并生成自己的interop.mshtml.dll互操作库,它会正常工作,您的机器上。但是,这并不另一台计算机没有安装IE9上正常工作。

This is an unsolvable problem. You can uninstall the PIA and generate your own interop.mshtml.dll interop library, it will work correctly on your machine. But it won't work correctly on another machine that doesn't have IE9 installed.

有可用一个很好的解决办法然而,的只是不使用XxxClass班的。只能使用接口类型。它应该像这样(在WinForms应用程序测试):

There's a good workaround available however, just don't use the XxxClass classes. Only use the interface types. Which ought to resemble this (tested in a Winforms app):

        var doc = (IHTMLDocument2)webBrowser1.Document.DomDocument;
        var headItems = (IHTMLElementCollection)doc.all.tags("head");
        var scriptObject = (IHTMLScriptElement)doc.createElement("script");
        scriptObject.type = @"text/javascript";
        //scriptObject.text = TTS.TTSWebFactory.GetJavascript();
        var node = (IHTMLDOMNode)headItems.item(null, 0);
        node.appendChild((IHTMLDOMNode)scriptObject);



在哪里我故意用强制转换为(IHTMLDOMNode),而不是(IHTMLHeadElement),因为较小的接口已经好到足以访问的项目的元素。

这篇关于MSHTML HTMLHeadElementClass COM错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆