如何获取某个Excel进程的窗口或进程句柄?

4
我们如何获取我们创建的Excel应用程序实例所属的Excel进程的应用程序窗口句柄或进程句柄? 我们正在使用Interop.Excel.dll版本1.3.0.0。似乎没有HWnd属性可供调用的应用程序类。 请注意,仅查找所有名称为excel.exe的进程不是解决方案,因为我们有许多并行运行的Excel实例,并且我们只想关闭特定的实例。
Excel.Application app = new Excel.Application();
// .. do something with excel here
app.Quit();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
// this is in some cases still not enough to get excel killed
uint processID;        
GetWindowThreadProcessId((IntPtr)hWnd, out processID); // how to get HWnd from this Excel application?
Process.GetProcessById((int)processID).Kill(); 
3个回答

2

应用程序类似乎没有可调用的HWnd属性。

Excel.Application类确实有一个Hwnd属性。

针对评论所说:

我们不使用Microsoft.Office.Interop.Excel.dll,而是使用缺少此属性的Interop.Excel.dll

我通常建议使用PIA(Microsoft.Office.Interop.Excel.dll)。如果您有不想这样做的充分理由,并且您正在使用的RCW出于某种原因没有公开该属性,则另一种选择是使用后期绑定,例如:

typeof(Excel.Application).InvokeMember("Hwnd", BindingFlags.GetProperty, null, app, null);

我们不使用Microsoft.Office.Interop.Excel.dll,而是使用缺少此属性的Interop.Excel.dll。 - codymanix

1

虽然我得到的所有答案都没有帮助,但无论如何还是感谢这些答案。我现在已经自己找到了一个解决方法:

我现在创建了一个工作进程,它定期检查超过一分钟的Excel进程。由于我的Excel处理永远不应该持续超过一分钟,所以我可以确定超过一分钟的Excel进程已经完成,因此我可以结束这个进程。

另一种方法是在实例化Excel进程之前获取所有Excel进程的列表。然后实例化后再次检查。新的pid就是新的Excel进程。请记得在此周围放置锁定语句以避免多线程问题。


0

您可以使用此结构来调用Windows API函数

    [DllImport("user32.dll")]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    IntPtr hWnd = FindWindow("XLMAIN", null);

但是在进行任何应用程序对象的操作之前,您必须先创建它,设置Visible=true,并使用下一行代码获取句柄。


3
这会找到任何 Excel 窗口,但不会定位到特定的 Excel 窗口。 - codymanix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接