监视程序并在崩溃时重新启动它

时间:2016-12-29 09:35:10

标签: c++ winapi signals

我有一个程序有时会崩溃。在这种情况下,我的程序应该重新启动。但是在通过任务管理器杀死它时,它应该结束 我创建了Monitor程序来监视实际程序并在崩溃时重新启动它 我使用发送实际程序终止它的信号来完成这项工作 我正在使用Windows操作系统 那就是我需要拦截发送到我的监控程序中的实际程序的信号

3 个答案:

答案 0 :(得分:1)

进程监视器应执行以下操作:

  1. 创建主进程,从而获取该进程的句柄。
  2. 等待该句柄发出信号,例如WaitForSingleObject,表示该进程已终止。
  3. 重新启动进程,获取新的进程句柄,然后转到2.
  4. 您应该安排监视程序始终创建主进程,并且两者都在作业对象中,该作业对象配置为在父进程终止时终止子进程。然后,当您希望终止程序时,只需终止监视器即可。然后,作业对象确保子程序也被终止。

    如果可能的话,你应该修复你的程序,使它不会崩溃。

答案 1 :(得分:1)

让我们暂时忽略你的问题,而不是解决问题。您正在寻找一种在异常退出时重新启动应用程序的方法,但仍然保留终止应用程序的能力(通过其GUI或任务管理器)。

Windows为此提供Application Recovery and Restart。它是系统内置的基础结构,允许您在未处理的异常(非正式地称为崩溃)的情况下注册应用程序以重新启动。

答案 2 :(得分:0)

当然你需要修复你的应用程序,因为它没有崩溃。只有这是很好的解决方案。但是正式地你可以做下一个(坏)

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