监视程序并在崩溃时重新启动它
我有一个程序有时会崩溃。在这种情况下,我的程序应该重新启动。但是,通过任务管理器杀死它,它应该结束。
我已经创建了Monitor程序,它监视实际程序并在崩溃时重新启动它。
我已经使用发送实际程序来终止它的信号来完成这项工作。
我正在使用Windows操作系统。
这就是我需要拦截监视程序并在崩溃时重新启动它
进程监视器应该做在我的监控程序发送到实际程序的信号如下:
- 创建的主要过程,并且由此获得的句柄处理。
- 等待处理成为信号的,例如与
WaitForSingleObject
,这表明该过程已经终止。 - 重新启动的过程中,获得一个新的进程句柄,然后去2
你应该安排一下监控程序总是创建的主要过程,并且都是在被配置为孩子作业对象父进程终止时将终止进程。然后当你想终止程序时,你只需要终止显示器。然后作业对象确保子程序也被终止。
如果可能的话,虽然,你应该修正你的程序,以便它不会崩溃。
但我应该能够终止程序而不终止'监视'程序。 – Priya
那么,监控程序如何知道这是故意终止?如果您确实想确保您的流程始终处于运行状态,那么我概述的流程就是要走的路。也许你需要想一想你想达到的目标。在我看来,你已经决定了你的解决方案(这是行不通的),并且不想招待其他任何东西。在这种情况下,祝你好运! –
你需要修复您的应用程序,因为它不会崩溃。只有这是很好的解决方案。然而,正式,你可以做下一个(坏)
void Ep()
{
// tag by * in begin of CommandLine
PWSTR CommandLine = GetCommandLine();
if (!CommandLine || *CommandLine != '*')
{
// monitor case
WCHAR FileName[MAX_PATH];
if (ULONG n = GetModuleFileName(0, FileName, RTL_NUMBER_OF(FileName)))
{
if (n < MAX_PATH)
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
PWSTR newCommandLine = (PWSTR)alloca((wcslen(CommandLine) + 2)*sizeof(WCHAR));
*newCommandLine = '*';
wcscpy(newCommandLine + 1, CommandLine);
// monitor and restart self in loop
BOOL bRestart;
do
{
bRestart = FALSE;
if (CreateProcessW(FileName, newCommandLine, 0, 0, 0, 0, 0, 0, &si, &pi))
{
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
ULONG exitcode;
bRestart = GetExitCodeProcess(pi.hProcess, &exitcode);
CloseHandle(pi.hProcess);
if (bRestart)
{
// 0xff - terminated by WerFault
// (int)exitcode < 0 - exception in process
bRestart = exitcode == 0xff || ((int)exitcode < 0);
}
}
} while (bRestart);
}
}
ExitProcess(0);
}
else
{
// main case
wcscpy(CommandLine, CommandLine + 1);
if (MessageBoxW(0, L"make crash ?", CommandLine, MB_YESNO) == IDYES)
{
__debugbreak();// simulate crash
}
ExitProcess(0);
}
}
让我们忽略你了片刻的问题,而是解决问题。您正在寻找一种在异常退出时重新启动应用程序的方式,但仍然保留终止应用程序的能力(通过其GUI或任务管理器)。
的Windows提供Application Recovery and Restart这一点。它是内置到系统中的基础设施,可以让你在未处理的异常的情况下,注册重新启动应用程序(非正式名称崩溃)。
为什么不修复你的程序,使它不会崩溃? – PaulMcKenzie
你的问题是什么?你为什么不修复你的程序? –
我的程序很少崩溃,像超时的情况下说,所以重新启动它再次使它工作正常。所以在这种情况下我的监视器程序应该重启它。 – Priya