首页 > 解决方案 > 关闭使用 CreateProcess() 打开的父进程后如何关闭消息框

问题描述

我想自动检查运行我的 .exe 文件的好坏。例如,对于这个二进制文件,我缺少 dll,当我使用 CreateProcess 时,它不会返回错误并为我提供系统 MessageBox(“Dll is missing”)。如果我手动关闭它,方法会返回 exitCode 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, &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;
} 

标签: c++winapi

解决方案


调用UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);before CreateProcess,并确保参数CREATE_DEFAULT_ERROR_MODE没有设置dwCreationFlags,让子进程继承父进程的错误模式。根据文档,这“不显示关键错误处理程序消息框,而是系统将错误发送到调用进程”。

可选择SetErrorMode(oldErrorMode);CreateProcess恢复之前的设置之后。


推荐阅读