Как сразу прекратить сбой приложения? - PullRequest
10 голосов
/ 25 декабря 2010

У меня есть приложение, которое иногда вызывает исключения. И мне нужно перезапустить его, если он упал. Но проблема в том, что у меня Windows 7 здесь, и когда происходит сбой приложения, Windows показывает мне красивое диалоговое окно с предложением закрыть приложение. Но само приложение все еще работает, пока я не нажму «Закрыть». Как избавиться от этого окна и заставить приложение завершиться немедленно без каких-либо диалоговых окон?

Ответы [ 3 ]

13 голосов
/ 25 декабря 2010

В идеале вы должны ловить все исключения в самой внешней области вашей программы. Тем не менее, иногда вы не можете позволить себе такие изменения, и диалоги сбоя не позволяют вам восстановиться после сбоя. В этих случаях вы можете отключить Windows Error Reporting , либо полностью, либо для конкретной программы.

В Windows 7: «Пуск» -> «Панель управления» -> «Центр поддержки» -> «Обслуживание» -> Проверить решения отчетов о проблемах -> Настройки

Обновление: чтобы полностью отключить интерфейс отчетов об ошибках, измените параметр реестра DontShowUI :

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ Отчеты об ошибках Windows \ DontShowUI

1 голос
/ 06 июня 2012

Вы можете использовать концепцию доктора Ватсона для обнаружения сбоя и перезапуска приложения. Используйте следующее:

Установите таймер как:

SetTimer( eIsDwwin, 30000, NULL);

Это будет проверять процесс доктора Ватсона через каждые 30 секунд в системном процессе, используя следующее:

void CMainFrame::OnTimer(UINT nIDEvent) {

    case eIsDwwin:
        HANDLE hndl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        DWORD dwsma = GetLastError();
        DWORD dwExitCode = 0;
        PROCESSENTRY32  procEntry={0};
        procEntry.dwSize = sizeof( PROCESSENTRY32 );
        Process32First(hndl,&procEntry);
        do {
            if(((!strcmpi(procEntry.szExeFile,"dwwin.exe"))|| 
                (!strcmpi(procEntry.szExeFile,"drwatson.exe"))||
                (!strcmpi(procEntry.szExeFile,"drwtsn32.exe"))||
                (!strcmpi(procEntry.szExeFile,"WerFault.exe"))) &&
                (procEntry.th32ParentProcessID == GetCurrentProcessId())) {

                WSACleanup();
                PostMessage( WM_CLOSE);
                Sleep(500);

        if(0==strcmpi(procEntry.szExeFile,"dwwin.exe")) {
            system("TASKKILL /IM dwwin.exe /F");
        } else if(0==strcmpi(procEntry.szExeFile,"drwatson.exe")) {
            system("TASKKILL /IM drwatson.exe /F");
        } else if(0==strcmpi(procEntry.szExeFile,"drwtsn32.exe")) {
            system("TASKKILL /IM drwtsn32.exe /F");
            } else if(0==strcmpi(procEntry.szExeFile,"WerFault.exe")) {
            system("TASKKILL /IM WerFault.exe /F");
        } else {
                    system("TASKKILL /IM WerFault.exe /F");
        }
                break;
        }
    } while(Process32Next(hndl,&procEntry));

        CloseHandle(hndl);
    break;
    }
}

Это изящно закроет приложение, которое упало.

Другим способом было бы использовать API-интерфейс Signal в Windows для обработки исключений и сбоев.

0 голосов
/ 25 декабря 2010

Незнание языка вашего приложения делает его немного сложным, но обычно вы можете справиться с этим, запустив ваше приложение в эквиваленте блока try / catch (как в C #, C ++ или Python).В псевдо-Csharp-ish-code:

bool done = false;
main()
{
    while( !done )
    {
        AppClass aclass = new AppClass();
        try
        {
            aclass->Run();
        }
        catch( Exception x )
        {
             LogErrorSomehow(x);
             delete aclass;
             continue;
        }
    }
}

По сути, лучший способ обойти ошибку «необработанное исключение» - это обработать исключение, перехватив его и выполнив соответствующее действие (даже если это действиеничего не делать).

В этом примере, если кто-то захочет закрыть ваше приложение, вы установите для значения «done» значение true и вернетесь из Run ().

...