我们如何获得属于我们创建的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();
答案 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并使用下一行代码获取句柄