【问题标题】:Find if process is responding without using System.Diagnostics.Process.Responding在不使用 System.Diagnostics.Process.Responding 的情况下查找进程是否响应
【发布时间】:2011-03-31 15:40:58
【问题描述】:

大家好。

这个问题是another one 的一部分,它已经解决了,我意识到我认为这是问题毕竟不是。仍然感谢我学到了一些东西。

我的应用程序使用 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 属性,那些拥有该属性的人我将他们的 Responding 属性发送到 MessageBox 并且当 IE 在 Windows 7 上没有响应但没有响应时,他们会正确报告经验。

我每 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?
  • @ChickSentMeHighE:IE8。请注意 Process.Responding 在 Windows 7 上运行良好,但在 XP 上运行良好。

标签: c# windows-xp


【解决方案1】:

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;
}

【讨论】:

  • 我没有想到,我的代码只检查第一个IE进程,然后报告回来。等一下,我会检查所有的。
  • 我的代码停止检查 Process.Responding 是否报告错误。注意 break 语句。
  • @Fábio Antunes:如果MainWindowHandle 不可用,Process.Responding 总是返回true,那么就不会到达 break 语句。
  • 我的朋友。谢谢。工作得很好,在 XP 中需要几秒钟才能识别 IE 停止响应,但最终它确实识别了。我使用了您在我的 Process 处理程序类中提供和实现的代码,它像时钟一样工作。如果你能向我解释你到底做了什么,我会很高兴的。
猜你喜欢
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2020-02-07
相关资源
最近更新 更多