Как закрыть окно сообщения после закрытия родительского процесса, открытого с помощью CreateProcess()

#c #winapi

#c #winapi

Вопрос:

Я хочу, чтобы автоматическая проверка была плохой или хорошей для запуска моих файлов .exe. Например, для этих двоичных файлов у меня отсутствуют dll, и когда я использую CreateProcess, он не возвращает ошибку и не предоставляет мне системное окно сообщений («Dll отсутствует»). Если я закрою его вручную, методы вернут код выхода STATUS_DLL_NOT_FOUND . Я хочу, чтобы по истечении некоторого времени ожидания все системные окна сообщений были закрыты с закрытием родительского процесса, и я могу получить свой STATUS_DLL_NOT_FOUND. Мне нужна полная автоматическая работа с моим кодом.Этот код может закрывать открытые вложенные диалоги, но не может закрывать ящики сообщений.

 int main()
{
    HANDLE                               hJob;
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
    PROCESS_INFORMATION                  pi = { 0 };
    STARTUPINFO                          si = { 0 };
    hJob = CreateJobObject(NULL, NULL);

    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, amp;jeli, sizeof(jeli));

    TCHAR szCmdline[] = TEXT(" -R:mm");
    si.cb = sizeof(si);
    CreateProcess(
        executableFiles[0].c_str(),
        szCmdline, 
        NULL, 
        NULL, 
        FALSE,
        CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB /*Important*/, 
        NULL, 
        NULL, 
        amp;si, 
        amp;pi);

    AssignProcessToJobObject(hJob, pi.hProcess); // Does not work if without CREATE_BREAKAWAY_FROM_JOB

    ResumeThread(pi.hThread);

    if (WaitForSingleObject(pi.hProcess, 3000) == WAIT_TIMEOUT)
    {
        EnumWindows(amp;SendWMCloseMsg, pi.dwProcessId);
        if (WaitForSingleObject(pi.hProcess, 2000) == WAIT_TIMEOUT)
        {

            TerminateProcess(pi.hProcess, 0);

            DWORD dwExitCode = 0;
            GetExitCodeProcess(pi.hProcess, amp;dwExitCode);

            const DWORD result = WaitForSingleObject(pi.hProcess, 2000);
            if (result == WAIT_OBJECT_0) 
            {
                if (dwExitCode == STATUS_DLL_NOT_FOUND)
                {
                    std::cout << "Dll is missing" << std::endl;
                }
            }
            else 
            {
                std::cout << "bad case" << std::endl;
            }
        }
    }
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(hJob);
    return 0;
} 
 

Ответ №1:

Вызовите UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); before CreateProcess и убедитесь, что CREATE_DEFAULT_ERROR_MODE это не задано в dwCreationFlags параметре, чтобы дочерний процесс унаследовал режим ошибки родительского процесса. Согласно документам, это «не отображает окно сообщения обработчика критических ошибок, вместо этого система отправляет ошибку вызывающему процессу«.

Необязательно SetErrorMode(oldErrorMode); после CreateProcess восстановления предыдущей настройки.