在不使用System.Diagnostics.Process.Responding的情况下查找进程是否响应

今天是个好日子。

这个问题是另一个问题的一部分,它已经解决了,我意识到我认为这毕竟是问题,但事实并非如此。 还是要感谢我,我学到了很多东西。

我的应用程序使用IE进行大量工作,IE不时被重定向到一个网站,其中包含一些糟糕的Javascript代码,最终阻止了IE界面。 一旦我的应用程序上的所有内容都在同一个Thread上运行,就会阻止我的应用程序。

为了解决这个问题,在启动时我的应用程序在另一个Thread中运行一个static method ,每15秒做一次简单的检查IE是否响应,如果IE没有响应,他关闭所有进程,解放我的锁定应用程序主Thread然后我的应用程序可以恢复其工作。

要查找IE进程是否正在响应,我有一个简单的代码,如下所示:

 bool terminate = false; foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses()) { if (exe.ProcessName.StartsWith("iexplore")) { if (exe.Responding == false) { terminate = true; break; } } } // Code to close all IE process's... 

为了使Process.Responding属性查找进程是否正在响应,并根据MSDN上的信息,此属性需要另一个名为MainWindowHandle属性才能完成检查过程。 如果MainWindowHandle不可用,即使进程没有响应, Process.Responding总是返回true。

由于某些我不知道的原因。 在Windows XP中, MainWindowHandle不可用,因此Responding不准确。

这就是为什么我需要知道另一种方法来查找特定进程是否在Windows XP中响应。

任何帮助表示赞赏,谢谢。

PS:如果你在这里寻找一个网站来冻结IE,请访问: http : //aboutmycollege.com/

编辑:遵循0xA3建议:

我经历了所有IE进程的检查, MainWindowHandle他们是否有MainWindowHandle属性,那些拥有该属性的人我将他们的Responding属性发送到MessageBox,当IE在Windows 7上没有响应但在XP上没有响应时他们正确报告。

我每15秒执行一次这段代码:

  foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses()) { if (exe.ProcessName.StartsWith("iexplore")) { if (exe.MainWindowHandle == IntPtr.Zero) { System.Windows.Forms.MessageBox.Show("Process doesn't have MainWindowHandle"); } else { System.Windows.Forms.MessageBox.Show("Process Responding: " + exe.Responding.ToString()); } } } 

在Windows 7和Xp中,他报告没有MainWindowHandle属性的IE的进程,并且在Windows 7中,他还在IE没有响应时正确报告。 但是在XP中,所有带有MainWindowHandle IE进程都会响应,即使它们不是。

IE是特殊的,因为每个选项卡都有自己的进程,还有一个额外的父IE进程。 实际上,只有父进程才有一个有效的MainWindowHandle

您是否检查过所有这些进程的MainWindowHandle是否为空? 如果不是,我认为您的代码也应该在XP上按预期工作。

更新

由于检查所有IE实例没有帮助,我接下来要尝试修改Process.Responding使用的超时。 该属性在内部调用SendMessageTimeout api函数,然后检查返回值是否发生超时。 如果是这样,则假定该过程挂起。 超时是5秒的硬编码值。

您可以使用P / Invoke自己调用SendMessageTimeout并改变超时。 可能更短的值会在Windows XP上产生更好的结果:

 [DllImport("user32.dll", CharSet=CharSet.Auto)] static extern IntPtr SendMessageTimeout( HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam, int flags, int timeout, out IntPtr pdwResult); const int SMTO_ABORTIFHUNG = 2; bool IsResponding(Process process) { HandeRef handleRef = new HandleRef(process, process.MainWindowHandle); int timeout = 2000; IntPtr lpdwResult; IntPtr lResult = SendMessageTimeout( handleRef, 0, IntPtr.Zero, IntPtr.Zero, SMTO_ABORTIFHUNG, timeout, out lpdwResult); return lResult != IntPtr.Zero; }