简体   繁体   中英

How to wait for child process when CreateProcess creates 2 process viz. rundll32 process which creates internally windows photo viewer Process

在此处输入图片说明 I have created process using CreateProcess() to open image using windows photo viewer. Since windows photo viewer is not .exe, it run with rundll32.exe, hence creating 2 process. so rundll32 becomes the parent process and windows photo viewer is child process. Now I want to wait for child process to be created. How to wait for child process.

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.

It is waiting for infinite time, and in case if I am giving some time in milisecond (WaitForSingleObject(pi.hProcess, 500);) then it is returning WAIT_TIMEOUT.

I have attached the image, whenever I am calling create process it create two process for each image, as you can see in attachment. Closing of rundll32.exe from taskmanger closes both the process as well as image window also, where as rundll32.exe *32 neither closes the rundll32.exe nor the windows image viewer.

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

This code return proper childProcess ID as 12504. But from create process the ID retrieved from pi.dwProcessId is 12132.

Now my requirement is to wait for the Process ID 12504 until it is not created. I have tried this using the code written below.

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

It is working but any alternate way I am searching.

Basically run32dll.exe is window host process executable used to host any kind of DLL application. I never saw run32dll hosting executable (Might be wrong here). Your example is completely based on window dll hosting on run32dll executable. Hence first correction is run32dll is not parent and window image view is not child process. you can cross verify this in process explorer. 在此处输入图片说明

code present in this link also return zero child processes under run32dll.exe.

Now lets come to your question, you want to check weather window photo viewer is opened or not. in this case, your own code will help you with the same.

Following are few example:

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.

Following code with wrong image path will not hold execution since image viewer is not opened:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM