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


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

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

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

GetActiveObject(ref _guid, _ptr, out objApp);

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


1821
2018-04-20 21:27


起源

你能给我一个示例如何使用GetActiveObject方法吗? - Higune


答案:


一旦通过流程ID识别流程,就可以获得 Process.MainWindowHandle 然后使用它 AccessibleObjectFromWindow API 访问该进程的Excel对象模型。

这篇文章 在Shimmed Automation加载项中获取应用程序对象 作者Andrew Whitechapel详细描述了这种技术,以及示例代码。

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

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实例并获取对象模型的访问权限。

希望这可以帮助,

麦克风


12
2018-04-20 22:11



谢谢,这正是我的期待。 - Vic
没问题,维克,很高兴它适合你。这不是一个简单的问题,并不为人所熟知,但Andrew Whitechapel的文章非常清楚。祝你好运! - Mike Rosenblum
文章已关闭,但这是我发现的代码的pastebin pastebin.com/F7gkrAST - Simon Woker


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


2
2018-04-20 22:03





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等于特定值。


-2
2018-04-20 21:39



谢谢你的快速回答,这里的问题是我不想杀死这个过程,我需要获得Excel实例来使用它,更具体地说我需要粘贴一些信息。 - Vic