如何从ROT获取progID?

时间:2018-03-21 12:58:04

标签: c# excel com interop

简介

我正在尝试遍历ROT(运行对象表)并搜索COM对象的特定progID。就我而言,progID应为Excel.Application

例如,如果我有一个运行excel的实例,我会得到Excel.Application这样的:{/ p>

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

问题:

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

目前的做法:

由于Marshal.GetActiveObject想要一个progID,我试图通过ROT并查找当前存在的所有progID:

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
  • 我无法从Type找出GetType()ppunkObject的正确{。}}。
  • ppszDisplayName有时会给我一个excel文档的路径,有时候是当前打开的工作簿的标题。

问题:

  • 有没有办法用这种方法识别正确的COM对象?如果不是,
  • 是否可以一般从ROT获得正确的progID

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

附加代码:

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

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

[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);

1 个答案:

答案 0 :(得分:0)

<强>解决方案:

似乎没有办法从ROT中获取正确的//Just add RewriteBase / //after RewriteEngine On //and you are done.... //so it should be RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] (并且它不会有帮助,因为progID例如没有给出特定的实例)。但是,如果您知道,文件将存储在哪里(路径的一部分似乎已足够)。

完整代码(工作示例):

Excel.Application

很多文字,简短的说法:如果你只知道路径的一部分或工作簿的文件名,那么这个片段基本上就会给你Excel COM对象。