.net документ пишут с помощью mshtml - PullRequest
4 голосов
/ 02 марта 2011

Я использую mshtml для разбора html.(версия 7.0.3300.0, C: \ Program Files \ Microsoft.NET \ Первичные сборки взаимодействия \ Microsoft.mshtml.dll).

HTMLDocumentClass имеет метод записи, поэтому я использовал его, но он вызывает ComException с ErrorCode:2147352571 и сообщение: Несоответствие типов.В чем причина?Если метод записи HTMLDocumentClass не будет использоваться, почему он определен?

    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;
    }

1 Ответ

11 голосов
/ 02 марта 2011

Хорошо, я нашел это.Это интересный режим отказа.Все PIA для Microsoft.mshtml, которые я установил на компьютере, устарели.Не менее 4 из них, все версии 7.0.3300.0 с целевым значением времени выполнения 1.0.3705 (что довольно старо).

Причиной является класс взаимодействия fooClass, который генерируется средством импорта библиотеки типов.Это синтетический класс, он существует для упрощения работы с событиями, в COM они выполняются совсем по-другому.Класс представляет собой упрощенную версию всех объединенных методов всех интерфейсов.Текущая версия SDK HTMLDocument Coclass объявлена ​​следующим образом (из 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;
};

Если вы используете Object Browser в библиотеке взаимодействия, вы увидите, что HTMLDocumentClass отсутствует методы интерфейса для IHTMLDocument6, IDocumentSelector и IHTMLDOMConstructor.Используемый вами метод write () минует эти интерфейсы.

Это означает, что если вы используете HTMLDocumentClass.write (), вы вызовете неправильный метод .Исключение возникает потому, что любой вызываемый метод не радует аргумент.Конечно, это не так.

Конечно, это неприятный режим отказа.Это произошло потому, что Microsoft нарушила очень жесткие требования COM, для изменения интерфейса COM или coclass требуется другой guid.Атрибут [uuid] в приведенном выше объявлении.Это, однако, также делает новые версии Internet Explorer полностью несовместимыми со старым кодом, который его использует.Рок и трудное место, обратная совместимость для Microsoft весьма священна.Порядок реализации интерфейса в коклассе обычно не является проблемой для обычных клиентов COM.За исключением .NET, он нарушает компоновку синтетического типа XxxClass, который генерирует tlbimp.

Я никогда не видел случая, когда этот синтетический класс действительно требовался, и никогда не использовал его сам.Вы всегда можете получить правильный указатель интерфейса, приведя к C #, который вызывает QueryInterface () и всегда возвращает правильный указатель независимо от версии.Ваша альтернатива - правильный обходной путь.

...