简体   繁体   English

我如何使用Marshal.QueryInterface?

[英]How do I use Marshal.QueryInterface?

I am trying to work with some embedded objects in Word documents. 我正在尝试使用Word文档中的一些嵌入对象。 An earlier poster told me that this is not straight forward. 早先的一张海报告诉我,这不是直截了当的。 Here is an excerpt of the linked answer: 以下是相关答案的摘录:

"As I mentioned earlier, utilizing the embedded object's programming model to perform the save is something of a shortcut. There is a more involved solution that will work with any embedded object. In order for the object to be embedded in the first place, it must support one of the COM IPersist interfaces (ie IPersistStorage, IPersistStreamInit, IPersistFile, etc). Therefore, an embedded object can always be extracted by calling Marshal.QueryInterface on the OLEFormat.Object (to determine the appropriate persistance interface), casting accordingly and then calling the appropriate method. Depending on which persistence interface you use, you may need to call some additional methods to expose the appropriate storage over the top of a file. Also, depending on the type of embedded object, you may still need to activate the object prior to being able to successfully QueryInterface for the persistance interfaces." “正如我前面提到的,利用嵌入式对象的编程模型来执行保存是一种快捷方式。有一个更复杂的解决方案可以用于任何嵌入式对象。为了将对象嵌入到第一位,它必须支持其中一个COM IPersist接口(即IPersistStorage,IPersistStreamInit,IPersistFile等)。因此,可以通过调用OLEFormat.Object上的Marshal.QueryInterface(以确定适当的持久性接口)来提取嵌入对象,并相应地进行转换。然后调用适当的方法。根据您使用的持久性接口,您可能需要调用一些其他方法来在文件顶部公开相应的存储。此外,根据嵌入对象的类型,您可能仍需要激活能够成功查询持久性接口的QueryInterface之前的对象。“

So I am interested in exposing which interface the object is implementing. 所以我有兴趣公开对象正在实现的接口。 The closest I could find is here . 我能找到的最接近的是这里 The code so far is below and any help with the Marshal.QueryInterface is greatly appreciated. 到目前为止的代码如下,非常感谢Marshal.QueryInterface的任何帮助。

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

Marshal.QueryInterface shouldn't be necessary - if you take a COM object and cast it to a COM interface type, .NET does the QueryInterface call for you. Marshal.QueryInterface不是必需的 - 如果您使用COM对象并将其转换为COM接口类型,.NET将为您执行QueryInterface调用。 That is, you can write: IPersistStorage persist = (IPersistStorage) obj; 也就是说,你可以写: IPersistStorage persist = (IPersistStorage) obj;

However it's not clear to me which object in the code implements IPersistStorage , IPersistStreamInit etc. 但是我不清楚代码中的哪个对象实现了IPersistStorageIPersistStreamInit等。

I am not sure what you intend to do but calling QueryInterface can be done. 我不确定你打算做什么但是可以调用QueryInterface The only problem is that you have a ProgID here and you need to get the CLSID from it first. 唯一的问题是你在这里有一个ProgID ,你需要先从它获取CLSID You can do by pInvoking the CLSIDFromProgId function. 您可以通过pInvoking CLSIDFromProgId函数来完成。

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

And then, you can call this as follows: 然后,您可以按如下方式调用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM