如何确定使用ShellExecuteEx创建的进程是否拥有一个窗口?

时间:2015-05-05 11:12:41

标签: c++ mfc shellexecute shellexecuteex

我正在使用SHELLEXECUTEINFO shExInfo = { 0 }; shExInfo.cbSize = sizeof(shExInfo); shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; shExInfo.hwnd = 0; shExInfo.lpVerb = L"runas"; // Operation to perform shExInfo.lpFile = windowStringContainingAppPath.c_str(); // Application to start shExInfo.lpParameters = windowStringContainingAppParameters.c_str(); // Additional parameters shExInfo.lpDirectory = 0; shExInfo.nShow = SW_SHOW; shExInfo.hInstApp = 0; if(ShellExecuteEx(&shExInfo)) { WaitForSingleObject(shExInfo.hProcess, INFINITE); DeleteFile(wsMesh3dx64Parameter.c_str()); CloseHandle(shExInfo.hProcess); } 来运行外部应用程序:

WaitForSingleObject(shExInfo.hProcess, INFINITE);

一切都运行良好但是这个外部应用程序存在计划外行为,在关闭其主窗口后,其进程仍处于活动状态。 这可以防止WaitForSingleObject(shExInfo.hProcess, INFINITE);返回,我必须手动终止该过程。

相反,我正在寻找一种方法来替换struct Porcess_ID_HWND { DWORD processID; HWND processhWnd; }; BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { Porcess_ID_HWND*info = (Porcess_ID_HWND*)lParam; DWORD processID; GetWindowThreadProcessId(hWnd, &processID); if (processID == info->processID){ info->processhWnd = hWnd; return FALSE; } return TRUE; } 一个循环,该循环检查外部进程是否拥有一个窗口,如果没有终止它。

这就是我的想法,但如果有更好的方法,请为我​​指出。

更新

感谢Robson的回答,我设法按照我的意图行事:

if(ShellExecuteEx(&shExInfo))
{
    DWORD dwProcessID = GetProcessId(shExInfo.hProcess);

    Porcess_ID_HWND info;
    info.processID = dwProcessID;
    // wait for window to appear
    do
    {
        info.processhWnd = NULL;
        EnumWindows(EnumWindowsProc, (LPARAM)&info);

    } while (!info.processhWnd);

    // wait for window to close
    do
    {
        info.processhWnd = NULL;
        EnumWindows(EnumWindowsProc, (LPARAM)&info);

    } while (info.processhWnd);

    //WaitForSingleObject(shExInfo.hProcess, INFINITE);

    DeleteFile(wsMesh3dx64Parameter.c_str());

    CloseHandle(shExInfo.hProcess);
}

我的循环:

{{1}}

1 个答案:

答案 0 :(得分:3)

http://forums.codeguru.com/showthread.php?392273-RESOLVED-How-to-get-window-s-HWND-from-it-s-process-handle

找到了一个很好的答案
1)
HAVE: Process ID, NEED: Process handle
Solution: OpenProcess()

2)
HAVE: Process handle, NEED: Process ID
Solution: GetProcessId()

3)
HAVE: Window handle, NEED: Process ID
Solution: GetWindowThreadProcessId()

4)
HAVE: Window handle, NEED: Process handle
Solution: Use 3) and then 1)

5)
HAVE: Process ID, NEED: Window handle
Solution: EnumWindows(), then in the callback function do 3) and check if it matches your process ID.

6)
HAVE: Process handle, NEED: Window handle
Solution: 2) and then 5)

所以你遇到的情况6.如果没有窗口句柄的进程ID与你的shExInfo.hProcess的进程ID匹配,那么shExInfo.hProcess没有窗口