我有一个有时会导致异常的应用程序。如果它崩溃了,我需要重新启动它。但问题是,我这里有 Windows 7,当应用程序崩溃时,Windows 会向我显示一个不错的对话框,其中包含关闭应用程序的建议。但应用程序本身仍在运行,直到我单击“关闭”。如何摆脱此窗口并使应用程序立即终止而没有任何对话框?
3 回答
理想情况下,您将捕获程序最外部范围内的所有异常。但是,有时您无法进行此类更改,并且崩溃对话框会阻止您从崩溃中恢复。在这些情况下,您可以考虑完全或针对特定程序禁用Windows 错误报告。
在 Windows 7 上:启动 Orb -> 控制面板 -> 操作中心 -> 维护 -> 检查问题报告的解决方案 -> 设置
更新:要完全禁用错误报告 UI,请更改DontShowUI注册表设置:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows 错误报告\DontShowUI
您可以使用 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 来处理异常和崩溃。
不了解应用程序的语言会有点困难,但您通常可以通过在相当于 try / catch 块(如在 C#、C++ 或 Python 中)中运行应用程序来处理它。在伪 Csharp-ish 代码中:
bool done = false;
main()
{
while( !done )
{
AppClass aclass = new AppClass();
try
{
aclass->Run();
}
catch( Exception x )
{
LogErrorSomehow(x);
delete aclass;
continue;
}
}
}
本质上,解决“未处理的异常”错误的最佳方法是通过捕获异常并采取适当的措施来处理异常(即使该措施什么也没做)。
在此示例中,如果有人想关闭您的应用程序,您可以将“done”值设置为 true 并从 Run() 返回。