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

时间:2011-01-20 11:52:44

标签: .net excel com interop office-interop

我们如何获得属于我们创建的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 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

虽然我得到的所有答案都没有帮助,但谢谢你的答案。我现在找到了一个解决方法:

我现在创建了工作流程定期检查超过一分钟的Excel流程。由于我的Excel处理时间不应超过一分钟,我可以确定超过一分钟的excel进程已完成,因此我可以 kill 此过程。

现在我想到的另一种方法是在实例化excel进程之前获得所有excel进程的列表。然后实例化后再次检查。新的pid是新的excel过程。请记住在此处添加 lock 语句以消除多线程问题。

答案 2 :(得分:0)

您可以将此构造用于调用Windows API函数

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

但是你必须在使用Application对象进行任何操作之前 - 创建它,设置Visible = true并使用下一行代码获取句柄