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

我正在使用C#,我需要通过它的进程ID来获得一个特定的Excel实例; 我从另一个应用程序获得我需要的实例的进程ID,但是我不知道该怎么办,我不知道如何在给定进程ID的情况下获得一个正在运行的实例。

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

此外,如果我能够得到我需要的Excel实例的CLSID,使用进程ID,那么我可能会打电话给

GetActiveObject(ref _guid, _ptr, out objApp); 

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

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

这篇由Andrew Whitechapel 在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实例。

希望这可以帮助,

麦克风

ROT项目不用CLSID标记。 ROT从寄存器返回一个DWORD,用作Unregister的标识符。 我以前遇到过这个问题,解决这个问题的唯一方法就是将一些加载项加载到每个可直接与之通信的Excel中。

 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等于特定值的所有进程。