Найти, если процесс отвечает, не используя System.Diagnostics.Process.Responding - PullRequest
1 голос
/ 18 августа 2010

Добрый день всем.

Эта проблема была частью еще одной , которая была решена, я понял, что то, что я думал, это проблема в конце концовне было.Тем не менее, благодаря этому я узнал пару вещей.

Мое приложение выполняет большую часть работы с IE, и время от времени IE перенаправляется на веб-сайт с некоторым плохим кодом Javascript, который в итоге блокирует интерфейс IE.И, следовательно, блокирование моего приложения, когда все в моем приложении выполняется на одном и том же Thread.

Чтобы противодействовать этой проблеме, при запуске мое приложение запускает static method в другом Thread, который каждые 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, но не на 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 он сообщает о процессах IE, которые неУ него есть свойство MainWindowHandle, и в Windows 7 он также правильно сообщает, что IE не отвечает.Но в XP все процессы IE с MainWindowHandle всегда отвечают, даже если они не отвечают.

1 Ответ

3 голосов
/ 18 августа 2010

IE является особенным, потому что каждая вкладка имеет свой собственный процесс плюс есть дополнительный родительский процесс IE. Фактически, только родительский процесс будет иметь действительный MainWindowHandle.

Вы проверяли, является ли MainWindowHandle нулевым для всех этих процессов? Если это не так, я думаю, что ваш код должен работать так же, как и ожидалось на XP.

Обновление

Поскольку проверка всех экземпляров IE не помогла, следующее, что я хотел бы попробовать, - изменить время ожидания, используемое Process.Responding. Свойство внутренне вызывает функцию API SendMessageTimeout, а затем проверяет возвращаемое значение, произошло ли время ожидания. Если это так, предполагается, что процесс зависает. Время ожидания является жестко заданным значением 5 секунд.

Вы можете позвонить SendMessageTimeout самостоятельно, используя P / Invoke, и изменить время ожидания. Возможно, более короткое значение даст лучшие результаты в 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...