0

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

我的循环:

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

1 回答 1

3

在http://forums.codeguru.com/showthread.php?392273-RESOLVED-How-to-get-window-s-HWND-from-it-s-process-handle找到了一个很好的答案

1)
HAVE:进程 ID,NEED:进程句柄
解决方案:OpenProcess()

2)
HAVE:进程句柄,NEED:进程ID
解决方案:GetProcessId()

3)
HAVE:窗口句柄,NEED:进程 ID
解决方案:GetWindowThreadProcessId()

4)
HAVE:窗口句柄,NEED:进程句柄
解决方案:使用 3) 然后 1)

5)
HAVE:进程 ID,NEED:窗口句柄
解决方案:EnumWindows(),然后在回调函数中执行 3) 并检查它是否与您的进程 ID 匹配。

6)
HAVE:进程句柄,NEED:窗口句柄
解决方案:2)然后 5)

所以你是第 6 种情况。那么如果没有窗口句柄的进程 ID 与你的 shExInfo.hProcess 的进程 ID 匹配,那么 shExInfo.hProcess 不拥有任何窗口

于 2015-05-05T11:28:49.277 回答