CreateProcess创建2进程时如何等待子进程。在内部创建Windows Photo Viewer进程的rundll32进程

时间:2019-02-19 07:00:13

标签: visual-c++ mfc createprocess waitforsingleobject

enter image description here我已经使用CreateProcess()创建了使用Windows照片查看器打开图像的过程。由于Windows Photo Viewer不是.exe,因此它与rundll32.exe一起运行,因此创建了2个进程。因此rundll32成为父进程,而Windows Photo Viewer是子进程。现在,我要等待子进程创建。如何等待子进程。

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

CString appStr = L"rundll32 \"C:\\Program Files\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen D:\\\\Results\\1.png";

CreateProcess(NULL,   // Name of program to execute
        CT2W(appStr),              // Command line
        NULL,                      // Process handle not inheritable
        NULL,                      // Thread handle not inheritable
        TRUE,                     // Set handle inheritance to FALSE
        0,                         // No creation flags
        NULL,                      // Use parent's environment block
        NULL,                      // Use parent's starting directory
        &si,                       // Pointer to STARTUPINFO structure
        &pi);

WaitForSingleObject(pi.hProcess, INFINITE); //its waiting for infinite time.

它正在等待无限的时间,并且如果我在毫秒内给出一些时间(WaitForSingleObject(pi.hProcess,500);),那么它将返回WAIT_TIMEOUT。

我已经附加了图像,每当我调用create process时,都会为每个图像创建两个过程,如附件所示。从taskmanger中关闭rundll32.exe会同时关闭进程和图像窗口,而rundll32.exe * 32不会关闭rundll32.exe或Windows图像查看器。

DWORD GetChildProcessID(DWORD dwProcessID)
{
    DWORD dwChildProcessID = -1;
    HANDLE          hProcessSnapshot;
    PROCESSENTRY32  processEntry32;

    hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnapshot != INVALID_HANDLE_VALUE)
    {
        processEntry32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hProcessSnapshot, &processEntry32))
        {
            do
            {
                if (dwProcessID == processEntry32.th32ParentProcessID)
                {
                    dwChildProcessID = processEntry32.th32ProcessID;
                    break;
                }
            } while (Process32Next(hProcessSnapshot, &processEntry32));

            CloseHandle(hProcessSnapshot);
        }
    }

    return dwChildProcessID; 
}

此代码返回正确的childProcess ID为12504。但是从创建过程中,从pi.dwProcessId检索的ID为12132。

现在我的要求是等待进程ID 12504,直到未创建为止。我已经使用下面编写的代码尝试过此操作。

while (1)
{
    dwChldProcessID = GetChildProcessID(pi.dwProcessId);
    hwnd = GetWindowHandle(dwChldProcessID);
    if (IsWindow(hwnd))
        break;
    else
        Sleep(100);
}

它正在工作,但是我正在搜索任何其他方式。

1 个答案:

答案 0 :(得分:0)

基本上,run32dll.exe是窗口宿主进程可执行文件,用于托管任何种类的DLL应用程序。我从未见过run32dll托管可执行文件(这里可能是错误的)。您的示例完全基于run32dll可执行文件上的窗口dll托管。因此,首先要纠正的是run32dll不是父进程,并且窗口图像视图不是子进程。您可以在流程浏览器中对此进行交叉验证。 enter image description here

this链接中存在的

代码在run32dll.exe下也返回零个子进程。

现在让我们问您一个问题,您要检查天气窗口照片查看器是否打开。在这种情况下,您自己的代码将为您提供帮助。

以下是几个示例:

CString appStr = L"rundll32 \"C:\\Program Files (x86)\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen C:\\download.png";

    BOOL result = CreateProcess(NULL,   // Name of program to execute
        CT2W(appStr),              // Command line
        NULL,                      // Process handle not inheritable
        NULL,                      // Thread handle not inheritable
        TRUE,                     // Set handle inheritance to FALSE
        0,                         // No creation flags
        NULL,                      // Use parent's environment block
        NULL,                      // Use parent's starting directory
        &si,                       // Pointer to STARTUPINFO structure
        &pi);
    WaitForSingleObject(pi.hProcess, INFINITE); //it will wait until you are not closing photo view since image is loaded successfully.

由于未打开图像查看器,以下带有错误图像路径的代码将无法执行:

CString appStr = L"rundll32 \"C:\\Program Files (x86)\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen C:\\dowdsdsdnload.dspng";

            BOOL result = CreateProcess(NULL,   // Name of program to execute
                CT2W(appStr),              // Command line
                NULL,                      // Process handle not inheritable
                NULL,                      // Thread handle not inheritable
                TRUE,                     // Set handle inheritance to FALSE
                0,                         // No creation flags
                NULL,                      // Use parent's environment block
                NULL,                      // Use parent's starting directory
                &si,                       // Pointer to STARTUPINFO structure
                &pi);
            WaitForSingleObject(pi.hProcess, INFINITE); //it will wait until you are not closing photo view since image is loaded successfully.