How close message box after closing parent process opened using CreateProcess()

Viewed 62

I want auto check bad or good for run my .exe files. For example for this binaries I have missing dll's, and when I use CreateProcess it's not return error and provide me system MessageBox("Dll is missing"). If I close it by hand, methods return exitCode STATUS_DLL_NOT_FOUND. I want that from some timeout all system message boxes will be closed with closing parent process and i can get my STATUS_DLL_NOT_FOUND. Me need full automatically work from my code.This code can closed opened sub dialogs, but can't close messageboxes.

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, &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, 
        &si, 
        &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(&SendWMCloseMsg, pi.dwProcessId);
        if (WaitForSingleObject(pi.hProcess, 2000) == WAIT_TIMEOUT)
        {

            TerminateProcess(pi.hProcess, 0);

            DWORD dwExitCode = 0;
            GetExitCodeProcess(pi.hProcess, &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 Answers

Call UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); before CreateProcess, and make sure that CREATE_DEFAULT_ERROR_MODE is not set in the dwCreationFlags parameter, so that the child process inherits the error mode of the parent. Per docs, this "does not display the critical-error-handler message box, instead, the system sends the error to the calling process".

Optionally SetErrorMode(oldErrorMode); after CreateProcess to restore the previous setting.

Related