【问题标题】:Retrieve Excel application from process id从进程 ID 中检索 Excel 应用程序
【发布时间】:2016-02-12 15:46:12
【问题描述】:

我正在使用 Process 类启动一个 Excel 应用程序。我可以使用下面的代码获取进程 ID 和主窗口句柄。

  Process xlP = Process.Start("excel.exe");
  int id = xlP.Id;
  int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;

这样就启动了一个 Excel 应用程序。如何使用进程 ID 和主窗口句柄引用这个特定的 Excel 实例?

我在这里看到过类似的问题,但答案是指向不再存在的网页的链接。

我基本上想要像下面这样的东西。

oExcelApp =  (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");

请不要必须使用Process.Start 方法启动 Excel 应用程序,如果不是,则不是。

【问题讨论】:

  • Process.Start 后 GetActiveObject 有什么问题?默认情况下,只会运行一个 Excel 实例。如果有多个实例,您需要遍历 ROT 表,获取每个实例并从 App.HWND 查找 processid
  • @AlexK。谢谢回复。我们使用的是 Windows 7,任何时候都可能打开多个 excel 实例。这就是为什么我认为进程 ID 会有所帮助,但认为我错了。抱歉,ROT 表是什么?可以告诉我这对我来说是新的
  • 只是好奇,你想用打开的 excel 文档做什么?
  • 基本上,当我打开一个 excel 应用程序时,我需要一个插件 (Bloomberg) 存在 - 我似乎获得该插件的唯一方法是使用 Process.Start 方法。然后我需要调用一些bloomberg函数来检查一些数据。我通常会使用bloomberg api,但是无法通过api获得数据

标签: c# .net excel-interop


【解决方案1】:

您可以使用以下代码访问所有正在运行的 Excel 实例并显示它们使用的窗口句柄:

[DllImport("ole32.dll")]
private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

private void button1_Click(object sender, EventArgs e)
{
    IRunningObjectTable lRunningObjectTable = null;
    IEnumMoniker lMonikerList = null;

    try
    {
        // Query Running Object Table 
        if (GetRunningObjectTable(0, out lRunningObjectTable) != 0 || lRunningObjectTable == null)
        {
            return;
        }

        // List Monikers
        lRunningObjectTable.EnumRunning(out lMonikerList);

        // Start Enumeration
        lMonikerList.Reset();

        // Array used for enumerating Monikers
        IMoniker[] lMonikerContainer = new IMoniker[1];

        IntPtr lPointerFetchedMonikers = IntPtr.Zero;

        // foreach Moniker
        while (lMonikerList.Next(1, lMonikerContainer, lPointerFetchedMonikers) == 0)
        {
            object lComObject;
            lRunningObjectTable.GetObject(lMonikerContainer[0], out lComObject);

            // Check the object is an Excel workbook
            if (lComObject is Microsoft.Office.Interop.Excel.Workbook)
            {
                Microsoft.Office.Interop.Excel.Workbook lExcelWorkbook = (Microsoft.Office.Interop.Excel.Workbook)lComObject;
                // Show the Window Handle 
                MessageBox.Show("Found Excel Application with Window Handle " + lExcelWorkbook.Application.Hwnd);
            }
        }
    }
    finally
    {
        // Release ressources
        if (lRunningObjectTable != null) Marshal.ReleaseComObject(lRunningObjectTable);
        if (lMonikerList != null) Marshal.ReleaseComObject(lMonikerList);
    }
}

【讨论】:

    【解决方案2】:

    添加对 Microsoft.Office.Interop.Excel 的引用并使用以下代码:

            Process xlP = Process.Start("excel.exe");
            int id = xlP.Id;
            int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;
    
            Excel.Application oExcelApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
    
            if(xlP.MainWindowTitle.Contains( oExcelApp.ActiveWorkbook.Name)   )
            {
                //Proceed further
            }
    

    【讨论】:

      猜你喜欢
      • 2013-09-14
      • 2020-10-28
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      相关资源
      最近更新 更多