如何获取隐藏的Excel应用程序实例的进程ID(PID)

3
我有一个 Microsoft.Office.Interop.Excel.Application 实例。为了确保 EXCEL.EXE 进程及时终止,我需要找到在创建 Application 对象时实例化的 ProcessID。
当 Excel Application 有一个窗口时,我可以通过查找它的 示例 来实现此目的。
那么,如果没有与 EXCEL.EXE 进程绑定的窗口呢?也就是说,当 excelApp.Hwnd 未设置时,是否有方法来做到这一点?

1
你从哪里获取 Microsoft.Office.Interop.Excel.Application - NineBerry
我在我的代码中创建了 Microsoft.Office.Interop.Excel.Application 的实例,并由我的代码使用。我需要避免在处理完它后留下孤立的 EXCEL.EXE。大多数情况下,这不是问题,因为我使用所有已知的策略来正确释放所有 COM 引用。然而,这还不够。我需要一种警报技术,让我知道是否失败。 - Zverev Evgeniy
我从未见过Excel.Application的Hwnd未设置的情况。您能展示一些样例代码吗,说明如何生成一个未设置Hwnd的Excel.Application? - NineBerry
不能找到实现接口的进程是COM中的基础。一个可怕的场景是,假设你获取PID,那么接下来你要做什么呢?Process.Kill()在Office程序中真的是一个非常、非常糟糕的想法。当你再次启动它时,你会触发自动恢复代码,这绝不是你在交互操作场景中想要发生的事情。解决真正的问题,而不是攻击症状。一个微不足道的方法是GC.Collect + GC.WaitForPendingFinalizers总是足够好的。你只需要将它放在正确的位置就行了。 - Hans Passant
@HansPassant 谁说我要杀死孤立的进程了?我说过吗?不要以自己为标准来评判别人。我需要找到“DETECT”孤立的进程并建立一个警报,提示“有需要关注的问题”。 - Zverev Evgeniy
显示剩余4条评论
1个回答

4

Application.Hwnd 具有有效的窗口句柄,即使应用程序没有可见的工作簿窗口,您也可以使用该句柄获取关联Excel应用程序的进程。

[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

Process GetExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp)
{
     int id;
     GetWindowThreadProcessId(excelApp.Hwnd, out id);
     return Process.GetProcessById(id);
}

void TerminateExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp)
{
     var process = GetExcelProcess(excelApp);
     if (process != null)
     {
          process.Kill();
     }
}

private void button1_Click(object sender, EventArgs e)
{
     // Create Instance of Excel
     Microsoft.Office.Interop.Excel.Application oXL = new Microsoft.Office.Interop.Excel.Application();
     try
     {
          // Work with oXL
     }
     finally
     {
          TerminateExcelProcess(oXL);
     }
}

注意:这个问题有一些答案解释了为什么通过C#自动化在Excel中完成工作后,Excel进程不会终止(除非你非常严谨地确保显式释放你使用的任何对象的每个引用)。

你的意思是说,即使是从ASP.NET w3wp进程和非交互式会话(session-0)如Windows服务进程创建的Excel实例也是真实存在的事件吗? - Zverev Evgeniy
是的。只要您成功创建了自动化对象,它就会有一个有效的窗口句柄。 - NineBerry
谢谢您的好消息。我将花时间测试它,并在成功后接受答案。 - Zverev Evgeniy

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