如何使用进程ID获取Excel实例或Excel实例CLSID?

时间:2009-04-20 21:27:57

标签: c# excel

我正在使用C#,我需要通过它的进程ID获取excel的特定实例;我从另一个应用程序获取了我需要的实例的进程ID,但我不知道还能做什么,我不知道如何根据进程ID获取excel的运行实例。

我在网上研究了很多,但我只看到使用Marshal.GetActiveObject(...)或Marshal.BindToMoniker(...)的例子,我不能使用,因为第一个返回在ROT中注册的第一个Excel实例,而不是我需要的那个,第二个要求您在尝试获取实例之前保存excel文件。

另外,如果我能够使用进程ID获取我需要的excel实例的CLSID,那么我可以调用

GetActiveObject(ref _guid, _ptr, out objApp);

最终将返回我需要的excel实例。

3 个答案:

答案 0 :(得分:12)

通过流程ID识别流程后,您可以获取Process.MainWindowHandle,然后将其与AccessibleObjectFromWindow API一起使用,以访问该流程的Excel对象模型。

Andrew Whitechapel撰写的文章Getting the Application Object in a Shimmed Automation Add-in详细介绍了这项技术,以及示例代码。

该文章中的关键代码从以下行开始:

int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle

在您的情况下可能更像是:

int excelId = 1234; // Change as appropriate!
int hwnd = (int)Process.GetProcessById(excelId).MainWindowHandle

其中'excelId'是您要查找的进程ID号。否则,代码应与文章中给出的代码基本相同。 (忽略他的代码是为加载项编写的事实;这方面不会影响你的需求,所以只需忽略它。)

如果您没有进程ID,那么您可以使用Process.GetProcessesByName,根据需要,您可以枚举每个实例并获取对每个Excel实例的控制权。

希望这有帮助,

麦克

答案 1 :(得分:2)

ROT条目未标记为CLSID。 ROT从Register返回一个DWORD,它用作取消注册的标识符。 我以前遇到过这个问题,我解决它的唯一方法就是在每个Excel中加载一些可以直接与之通信的加载项。

答案 2 :(得分:-3)

using System.Diagnostics;

   var eProcess = from p in Process.GetProcessesByName("EXCEL")
                   where p.Id == 3700 //whatever Id you have...
                   select p;

    foreach (var process in eProcess)
        process.Kill();

这将获得名为“EXCEL”的所有进程,其中进程ID等于特定值。