C# 如何使用进程 ID 获取 Excel 实例或 Excel 实例 CLSID?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/770173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get Excel instance or Excel instance CLSID using the Process ID?
提问by Vic
I'm working with C#, I need to obtain a specific instance of excel by it's process ID; I get the Process ID of the instance that I need from another application but I don't know what else to do, I don't know how can I get a running instance of excel given his process ID.
我正在使用 C#,我需要通过它的进程 ID 获取特定的 excel 实例;我从另一个应用程序获得了我需要的实例的进程 ID,但我不知道还能做什么,我不知道如何根据他的进程 ID 获得正在运行的 excel 实例。
I have researched a lot on the web, but I have only see examples of using Marshal.GetActiveObject(...) or Marshal.BindToMoniker(...), which I can't use since the first one returns the first Excel instance registered in the ROT and not precisely the one that I need, and the second one requires that you save the excel file before trying to get the instance.
我在网上研究了很多,但我只看到了使用 Marshal.GetActiveObject(...) 或 Marshal.BindToMoniker(...) 的示例,因为第一个返回第一个 Excel 实例,所以我无法使用在 ROT 中注册,而不是我需要的那个,第二个要求您在尝试获取实例之前保存 excel 文件。
Also, if I where able to get the CLSID of the excel instance that I need, using the process ID, then I may be able to call
另外,如果我能够使用进程 ID 获得所需的 excel 实例的 CLSID,那么我可以调用
GetActiveObject(ref _guid, _ptr, out objApp);
that ultimately will return the excel instance that I need.
最终将返回我需要的 excel 实例。
采纳答案by Mike Rosenblum
Once you identify the process via the process id, you can get the Process.MainWindowHandleand then use that along with the AccessibleObjectFromWindow APIto get access to the Excel object model for that process.
通过进程 ID 识别进程后,您可以获取Process.MainWindowHandle,然后将其与AccessibleObjectFromWindow API一起使用以访问该进程的 Excel 对象模型。
The article Getting the Application Object in a Shimmed Automation Add-inby Andrew Whitechapel describes this technique in detail, along with sample code.
Andrew Whitechapel撰写的文章在 Shimmed Automation Add-in 中获取应用程序对象详细描述了此技术以及示例代码。
The key code in that article for you begins at the line:
那篇文章中为您提供的关键代码从以下行开始:
int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle
Which in your case might look more like:
在您的情况下,它可能看起来更像:
int excelId = 1234; // Change as appropriate!
int hwnd = (int)Process.GetProcessById(excelId).MainWindowHandle
where the 'excelId' is the process id number that you are looking for. Otherwise, the code should be essentially the same as given in the article. (Ignore the fact that his code is written for an add-in; that aspect won't affect your needs here, so just ignore it.)
其中“excelId”是您要查找的进程 ID 号。否则,代码应该与文章中给出的基本相同。(忽略他的代码是为加载项编写的这一事实;该方面不会影响您在此处的需求,因此只需忽略它。)
If you do not have the process id, then you you would want to use Process.GetProcessesByName, whereby you could enumerate each one and grab control of each Excel instance with access to the object model, as needed.
如果您没有进程 ID,那么您可能需要使用Process.GetProcessesByName,这样您就可以枚举每个实例并根据需要获取每个 Excel 实例的控制权并访问对象模型。
Hope this helps,
希望这可以帮助,
Mike
麦克风
回答by Inisheer
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();
This gets all processes named "EXCEL" where the Process Id equals a specific value.
这将获取名为“EXCEL”的所有进程,其中进程 ID 等于特定值。
回答by Joel Lucsy
The ROT entries are not tagged with a CLSID. The ROT returns a DWORD from Register, which is used as a identifier for Unregister. I've run into this problem before and the only way I've solved it is to have some kind of add-in loaded into each Excel that you can communicate directly with.
ROT 条目没有用 CLSID 标记。ROT 从 Register 返回一个 DWORD,用作 Unregister 的标识符。我以前遇到过这个问题,我解决它的唯一方法是将某种加载项加载到您可以直接与之通信的每个 Excel 中。

