【问题标题】:How to immediately terminate crashed application?如何立即终止崩溃的应用程序?
【发布时间】:2011-05-30 13:06:03
【问题描述】:

我有一个有时会导致异常的应用程序。如果它崩溃了,我需要重新启动它。但问题是,我这里有 Windows 7,当应用程序崩溃时,Windows 会向我显示一个不错的对话框,其中包含关闭应用程序的建议。但应用程序本身仍在运行,直到我单击“关闭”。如何摆脱这个窗口并使应用程序立即终止而没有任何对话框?

【问题讨论】:

  • 另一个有用的解决方案是注册表设置HKEY_CURRENT_USER\Control Panel\Desktop 创建一个名为AutoEndTasks 的REG_SZ 条目并将其设置为1
  • 那么问题就变成了:如何立即终止特定(Process Id)崩溃的应用程序?

标签: debugging crash dr.watson


【解决方案1】:

理想情况下,您会在程序的最外部范围内捕获所有异常。但是,有时您没有进行此类更改的奢侈,并且崩溃对话框会阻止您从崩溃中恢复。在这些情况下,您可以考虑完全禁用Windows Error Reporting,或者针对特定程序禁用。

在 Windows 7 上:启动 Orb -> 控制面板 -> 操作中心 -> 维护 -> 检查问题报告的解决方案 -> 设置

更新:要完全禁用错误报告 UI,请更改 DontShowUI 注册表设置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows 错误报告\DontShowUI

【讨论】:

  • 不是我的应用程序崩溃了。并且此报告已禁用。但 Windows 仍然显示通知对话框,防止崩溃的可执行文件终止,直到您在那里按确定。
  • 更新了答案以包含注册表设置。
  • 我还有一个不是我的应用程序,它有时会崩溃。我想确保当它崩溃时,它会立即自动终止,而不需要用户在通知窗口中按下按钮。
  • 禁用错误报告设置 DontShowUI 为 DWORD 0
【解决方案2】:

您可以使用 Dr Watson 的概念来检测崩溃并重新启动应用程序。使用以下内容:

设置一个定时器,如:

SetTimer( eIsDwwin, 30000, NULL);

这将使用以下命令在系统进程中每 30 秒检查一次 Dr Watson 进程:

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

这将优雅地关闭崩溃的应用程序。

另一种方法是使用 Windows 中的 Signal API 来处理异常和崩溃。

【讨论】:

    【解决方案3】:

    不了解应用程序的语言会有点困难,但您通常可以通过在相当于 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() 返回。

    【讨论】:

    • 崩溃的应用程序不是我的。
    猜你喜欢
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 2013-12-13
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    相关资源
    最近更新 更多