首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从腐烂中获得progID?

如何从腐烂中获得progID?
EN

Stack Overflow用户
提问于 2018-03-21 12:58:04
回答 1查看 1.1K关注 0票数 1

简介:

我正在尝试迭代ROT (运行对象表),并搜索COM对象的特定progID。在我的例子中,progID应该是Excel.Application

例如,如果我有一个运行excel的实例,就会得到如下所示的Excel.Application

代码语言:javascript
复制
Excel.Application excel = (Excel.Application)Marshal.GetActiveObject("Excel.Application");

问题:

如果我有多个实例正在运行,这个调用基本上会给出任何实例,并且我无法识别正确的实例(例如,通过窗口标题.)。因此,我需要一个特定的实例,它可以通过打开的Workbook或窗口标题来标识。

当前方法:

由于Marshal.GetActiveObject想要一个progID,所以我试着浏览一下ROT,并查找当前存在的所有progID:

代码语言:javascript
复制
public static void Main(string[] args)
{
    if (GetRunningObjectTable(0, out IRunningObjectTable pprot) == 0)
    {
        pprot.EnumRunning(out IEnumMoniker ppenumMoniker);
        ppenumMoniker.Reset();

        var moniker = new IMoniker[1];

        while (ppenumMoniker.Next(1, moniker, IntPtr.Zero) == 0)
        {
            CreateBindCtx(0, out IBindCtx ppbc);
            pprot.GetObject(moniker[0], out object ppunkObject);

            moniker[0].GetDisplayName(ppbc, null, out string ppszDisplayName);
            moniker[0].GetClassID(out Guid pClassID);

            ProgIDFromCLSID(ref pClassID, out string lplpszProgID);
        }
    }

    // Excel excel = (Excel)Marshal.GetActiveObject("Excel.Application"); 
}

我注意到以下几点:

  • 每次ProgIDFromCLSID()给我打电话filenull
  • 我无法从TypeGetType()中识别正确的ppunkObject
  • ppszDisplayName有时给我提供excel文档的路径,有时提供当前打开的工作簿的标题。

问题:

  • 有办法用这种方法来标识正确的COM对象吗?如果没有,
  • 一般情况下,是否有可能从腐朽中获得正确的progID

另外,如果有更简单的方法来识别我的实例,请告诉我。

附加代码:

代码语言:javascript
复制
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

using Excel = Microsoft.Office.Interop.Excel.Application;

代码语言:javascript
复制
[DllImport("ole32.dll")]
private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable pprot);

[DllImport("ole32.dll")]
private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);

[DllImport("ole32.dll")]
private static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-22 14:11:08

解决方案:

似乎没有办法从ROT中获得适当的progID (而且也没有帮助,因为Excel.Application没有给出特定的实例)。但是,如果您知道文件的存储位置(路径的一部分似乎就足够了),这是可能的。

完整代码(工作示例):

代码语言:javascript
复制
// Microsoft.CSharp, 4.0.30319
// Microsoft.Office.Interop.Excel, 15.0.4420.1017

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

using Excel = Microsoft.Office.Interop.Excel;



public static void Main(string[] args)
{
    object ppunk = null;

    if (GetRunningObjectTable(0, out IRunningObjectTable pprot) == 0)
    {
        pprot.EnumRunning(out IEnumMoniker ppenumMoniker);
        ppenumMoniker.Reset();

        var moniker = new IMoniker[1];

        while (ppenumMoniker.Next(1, moniker, IntPtr.Zero) == 0)
        {
            CreateBindCtx(0, out IBindCtx ppbc);

            moniker[0].GetDisplayName(ppbc, null, out string ppszDisplayName);

            Marshal.ReleaseComObject(ppbc);

            // Identify by worksheet path
            if (ppszDisplayName.ToLower().Contains(".xls") && ppszDisplayName.ToLower().Contains("appdata"))
            {
                pprot.GetObject(moniker[0], out object ppunkObject);
                ppunk = ppunkObject;
            }
        }
    }

    if (ppunk != null)
    {
        Excel.Workbook workbook = ppunk as Excel.Workbook;
        Excel.Application excel = workbook.Application;

        // Do something
        dynamic title = workbook.FullName;

        excel.Quit();
    }
}



// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684004(v=vs.85).aspx
[DllImport("ole32.dll")]
private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable pprot);

// https://msdn.microsoft.com/de-de/library/windows/desktop/ms678542(v=vs.85).aspx
[DllImport("ole32.dll")]
private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);

多文本,短义:基本上,如果您只知道路径的一部分或工作簿的文件名,这个片段就会给您Excel对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49406971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档