How to obtain IServiceProvider and IMarkupServices from HTMLDocument (mshtml)
Im doing some test creating an instance of HTMLDocument this way:
object[] pageText = { "<p>some text...</p>" };
var document = new HTMLDocumentClass();
var document2 = (IHTMLDocument2)document;
document2.write(pageText);
and need to get a reference to a IMarkupServices.
This is the code I'm currently using:
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;
}
When i run it (it's hosted in a Console App) the following exception is thrown:
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
Note: What i'm trying to do is to unit test some objects i have implemented with mshtml. When i run the same code in an BHO (within Internet Explorer) it works fine.
Thank you very much
Edit: here´s the code I finaly used to get this working
I got it working by inspecting the following WatiN's implementation: http://www.java2s.com/Open-Source/CSharp/Web-Testing/WatiN/WatiN/Examples/MsHtmlBrowser/MsHtmlNativeBrowser.cs.htm based on Sheng Jiang helpful answer.
public class Program
{
[Guid("7FD52380-4E07-101B-AE2D-08002B2EC713")]
[InterfaceTypeAttribute(ComIn开发者_开发百科terfaceType.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);
}
}
QI for IMarkupServices after you loaded the document via the IPersistStreamInit interface, preferably with a Url moniker as a proxy.
精彩评论