C# 用mshtml编写.net文档
我正在使用mshtml进行html解析。(版本7.0.3300.0,C:\Program Files\Microsoft.NET\Primary Interop Assembly\Microsoft.mshtml.dll) HTMLDocumentClass有一个write方法,所以我使用了它,但它会引发ComException 错误代码:-2147352571和消息:类型不匹配。原因是什么?如果不使用HTMLDocumentClass的write方法,为什么要定义C# 用mshtml编写.net文档,c#,.net,document,mshtml,C#,.net,Document,Mshtml,我正在使用mshtml进行html解析。(版本7.0.3300.0,C:\Program Files\Microsoft.NET\Primary Interop Assembly\Microsoft.mshtml.dll) HTMLDocumentClass有一个write方法,所以我使用了它,但它会引发ComException 错误代码:-2147352571和消息:类型不匹配。原因是什么?如果不使用HTMLDocumentClass的write方法,为什么要定义 HTMLDocume
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): 如果在互操作库上使用对象浏览器,您将看到HTMLDocumentClass缺少IHTMLDocument6、IDocumentSelector和IHTMLDOMConstructor的接口方法。您正在使用的write()方法已通过这些接口 这意味着如果使用HTMLDocumentClass.write(),将调用错误的方法。引发异常是因为调用的任何方法都对参数不满意。当然不是 这当然是一种令人讨厌的失败模式。这是因为微软打破了非常严格的COM要求,更改COM接口或coclass需要不同的guid。上述声明中的[uuid]属性。然而,这也使得新版本的Internet Explorer与使用它的旧代码完全不兼容。在微软,向后兼容性是非常神圣的。在普通COM客户机中,coclass中接口实现的顺序通常不是问题。除了在.NET中,它打破了tlbimp生成的合成XXX类类型的布局
我从未见过这样的情况,即合成类实际上是必需的,而且我自己也从未使用过。通过在C#中强制转换始终可以获得正确的接口指针,该C#调用QueryInterface(),并且无论版本如何,始终返回正确的指针。你的选择是正确的解决方法 不要。相反,在HtmlAlityPack上使用.1。这是一个可以满足所有HTML解析需求的解决方案。因此,我不是在寻找解析解决方案,而是想知道我是否缺少一些关于接口和com对象的信息。这很难解释。使用doc.IHTMLDocument2_write()可以很好地工作。简直像是PIA里的一只虫子,难以置信。然而,使用该接口总是被推荐的,特别是对于VS2010,它具有嵌入互操作类型的特性。我发现HtmlAgilityPack在很多情况下失败了,坦率地说,我对它感到失望。它打破了最初的htmls,只要它没有关闭某些元素的标记,并且这些元素不必按规范(td、li和其他)关闭。因此,我添加了对c:\windows\system32\MSHTML.dll的引用,它的HTMLDocumentClass包含IHTMLDocument6、IDocumentSelector和IHTMLDOMConstructor的接口方法。但当使用write方法时,它会引发相同的错误?我(通过Reflector)确定WebBrowser控制文档(HtmlDocument)的write方法也会调用IHTMLDocument2的write方法。
[
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;
};