Как получить IServiceProvider и IMarkupServices из HTMLDocument (mshtml)

Я делаю тест, создавая экземпляр HTMLDocument следующим образом:

object[] pageText = { "<p>some text...</p>" };
var document = new HTMLDocumentClass();
var document2 = (IHTMLDocument2)document;
document2.write(pageText);

и нужно получить ссылку на IMarkupServices.

Это код, который я сейчас использую:

Guid IID_IMarkupServices = new Guid("3050F4A0-98B5-11CF-BB82-00AA00BDCE0B");
IMarkupServices markupServices = GetService<IMarkupServices>(document, ID_IMarkupServices);

static Guid HTMLDocumentClassGuid = new Guid("25336920-03F9-11CF-8FD0-00AA00686F13");
private static T GetService<T>(IHTMLDocument2 document, Guid riid)
{
    var serviceProvider = (IServiceProvider) document;
    object service;
    serviceProvider.QueryService(ref HTMLDocumentClassGuid, ref riid, out service);
    return (T)service;
}

Когда я запускаю его (он размещен в консольном приложении), возникает следующее исключение:

Unhandled Exception: System.InvalidCastException: Unable to cast COM object of type 'mshtml.HTMLDocumentClass' to interface type 'IServiceProvider'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{4C9A623C-FF69-3A3B-B592-43371C50DF88}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
at ConsoleApplication3.Program.GetService[T](IHTMLDocument2 document, Guid riid) in c:\users\admin\documents\visual studio 010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 35
at ConsoleApplication3.Program.Main(String[] args) in c:\users\admin\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 29

Примечание. Я пытаюсь выполнить модульное тестирование некоторых объектов, которые я реализовал с помощью mshtml. Когда я запускаю тот же код в BHO (в Internet Explorer), он работает нормально.

Большое Вам спасибо

Редактировать: вот код, который я наконец использовал, чтобы заставить это работать

Я заработал, проверив следующую реализацию WatiN: http://www.java2s.com/Open-Source/CSharp/Web-Testing/WatiN/WatiN/Examples/MsHtmlBrowser/MsHtmlNativeBrowser.cs.htm на основе полезного ответа Шэн Цзяна.

public class Program
    {
        [Guid("7FD52380-4E07-101B-AE2D-08002B2EC713")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IPersistStreamInit
        {
            void GetClassID(out Guid pClassID);
            int IsDirty();
            void Load(System.Runtime.InteropServices.ComTypes.IStream pStm);
            void Save(System.Runtime.InteropServices.ComTypes.IStream pStm, bool fClearDirty);
            void GetSizeMax(out long pcbSize);
            void InitNew();
        }

        [STAThread]
        static void Main(string[] args)
        {
            var anHtmlDocument = new HTMLDocumentClass();
            var aPersistStream = (WB.Program.IPersistStreamInit)anHtmlDocument;
            aPersistStream.InitNew();

            var anHtmlDocument2 = (IHTMLDocument2)anHtmlDocument;
            anHtmlDocument2.write(new object[] { "test <b> foo </b>" });
            anHtmlDocument2.close();

            while (anHtmlDocument.readyState != "complete")
            {
                //This is also a important part, without this DoEvents() appz hangs on to the “loading”
                Application.DoEvents();
            }

            var aMarkupService = (IMarkupServices)anHtmlDocument;

            IMarkupPointer aPointer;
            aMarkupService.CreateMarkupPointer(out aPointer);

            var anHtmlBody = (IHTMLBodyElement)anHtmlDocument.body;
            var aSelection = anHtmlBody.createTextRange();
            aSelection.findText("foo", 0, 0);
        }
    }

person nick2083    schedule 30.06.2011    source источник


Ответы (1)


QI для IMarkupServices после загрузки документа через интерфейс IPersistStreamInit, предпочтительно с ссылкой Моникер URL в качестве прокси.

person Sheng Jiang 蒋晟    schedule 30.08.2011
comment
Благодарность! Я обновил свой вопрос кодом, который я использовал, чтобы заставить его работать. - person nick2083; 23.12.2011