.net文件用mshtml写

我使用mshtml进行html解析。 (版本7.0.3300.0,C:\ Program Files \ Microsoft.NET \ Primary Interop Assemblies \ Microsoft.mshtml.dll)。

HTMLDocumentClass有一个write方法,所以我使用它,但它引发了与ErrorCode的ComException:-2147352571和消息:类型不匹配。 它是什么原因? 如果不使用HTMLDocumentClass的write方法,他们为什么定义?

HTMLDocumentClass getHTMLDocument(string html) { HTMLDocumentClass doc = new HTMLDocumentClass(); doc.write(new object[] { html }); // raises exception doc.close(); return doc; } HTMLDocumentClass getHTMLDocument2(string html) { HTMLDocumentClass doc = new HTMLDocumentClass(); IHTMLDocument2 doc2 = (IHTMLDocument2)doc; doc2.write(new object[] { html }); doc2.close(); return doc; } 

好的,我找到了。 这是一种有趣的失败模式。 我在机器上安装的所有Microsoft.mshtml PIA都已过时。 不少于4个,所有版本7.0.3300.0,运行时目标为1.0.3705(这是相当古老的)。

由类型库导入器生成的fooClass互操作类是原因。 它是一个合成类,它存在使事件更容易处理,它们在COM中完成得非常不同。 该类是所有接口的所有组合方法的扁平化版本。 HTMLDocument coclass的当前SDK版本声明如下(来自mshmtl.idl):

 [ uuid(25336920-03F9-11cf-8FD0-00AA00686F13) ] coclass HTMLDocument { [default] dispinterface DispHTMLDocument; [source, default] dispinterface HTMLDocumentEvents; [source] dispinterface HTMLDocumentEvents2; [source] dispinterface HTMLDocumentEvents3; interface IHTMLDocument2; interface IHTMLDocument3; interface IHTMLDocument4; interface IHTMLDocument5; interface IHTMLDocument6; interface IHTMLDOMNode; interface IHTMLDOMNode2; interface IDocumentSelector; interface IHTMLDOMConstructor; }; 

如果在互操作库上使用对象浏览器,您将看到HTMLDocumentClass 缺少 IHTMLDocument6,IDocumentSelector和IHTMLDOMConstructor的接口方法。 您正在使用的write()方法是通过这些接口。

这意味着如果你使用HTMLDocumentClass.write(),你将调用错误的方法 。 引发exception是因为调用的方法对参数不满意。 当然不是。

当然,这是一种令人讨厌的失败模式。 这是因为微软打破了一个非常困难的COM要求,更改COM接口或coclass需要一个不同的 guid。 上述声明中的[uuid]属性。 然而,这也使得新版本的Internet Explorer与使用它的旧代码完全不兼容。 摇滚和一个艰难的地方,向后兼容性在微软是非常神圣的。 在常规COM客户端中,coclass中的接口实现顺序通常不是问题。 除了在.NET中,它打破了tlbimp生成的合成XxxClass类型的布局。

我从来没有见过一个案例,其中合成类实际上是必需的,并且从不使用它。 您始终可以通过在C#中转换来获取正确的接口指针,该C#调用QueryInterface()并始终返回正确的指针,而不管版本如何。 您的替代方案是正确的解决方法。