How to use Marshal.QueryInterface?

I am trying to work with some built-in objects in Word documents. An early poster told me that it wasnโ€™t straightforward. Here is a snippet of a related answer:

โ€œAs I mentioned earlier, using built-in object modeling to perform a save is something like a shortcut. There is a more involved solution that will work with any built-in object. In order for an object to be embedded in the first place, it must support one of the IPersist COM Interfaces (i.e. IPersistStorage, IPersistStreamInit, IPersistFile, etc.) Therefore, an inline object can always be retrieved by calling Marshal.QueryInterface on OLEFormat.Object (to determine the corresponding persistence interface), casting and then calling the appropriate method. Depending on which persistence interface you use, you may need to call additional methods to identify the corresponding storage at the top of the file. Also, depending on the type of built-in object, you still have to activate the object before successfully QueryInterface for persistence. "

Therefore, I am interested in exposing which interface the object implements. The closest I could find is here . The code is still below, and any help with Marshal.QueryInterface is much appreciated.

// Opening the word document object missing = Type.Missing; this.document = wordApp.Documents.Open( ref fn, ref confirmConversions, ref readOnly, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing); foreach (Microsoft.Office.Interop.Word.InlineShape inlineShape in this.document.InlineShapes) { if (inlineShape.OLEFormat.ProgID != null) { switch (inlineShape.OLEFormat.ProgID) { // This is a pdf file case "AcroExch.Document.7": //Marshal.QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv); break; default: break; } } } 
+4
source share
2 answers

Marshal.QueryInterface not required: if you take a COM object and pass it to a COM interface type, .NET makes a QueryInterface call for you. That is, you can write: IPersistStorage persist = (IPersistStorage) obj;

However, I donโ€™t understand which object in the code implements IPersistStorage , IPersistStreamInit , etc.

+4
source

I'm not sure what you intend to do, but a call to QueryInterface can be made. The only problem is that you have a ProgID here, and you need to get the CLSID from it first. You can execute the pInvoking function CLSIDFromProgId.

 [DllImport("ole32.dll")] static extern int CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] string lpszProgID, out Guid pclsid); 

And then you can call it like this:

 Marshal.QueryInterface(IntPtr.Zero, CLSIDFromProgID(progID), out pInterface); 
+2
source

Source: https://habr.com/ru/post/1340774/


All Articles