C# 用mshtml编写.net文档

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

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

HTMLDocumentClass有一个write方法,所以我使用了它,但它会引发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):

如果在互操作库上使用对象浏览器,您将看到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;
};