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

How to find out if process created with ShellExecuteEx owns a window?

本文关键字:是否 拥有 窗口 程是否 何确定 ShellExecuteEx 创建      更新时间:2023-10-16

我正在使用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);
}

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

1) 具有:进程 ID,需要:进程句柄 解决方案:OpenProcess() 2) 具有:进程句柄,需要:进程 ID 解决方案:GetProcessId() 3) 具有:窗口句柄,需要:进程 ID 解决方案:GetWindowThreadProcessId() 4) 具有:窗口句柄,需要:进程句柄 解决方案:使用 3) 然后使用 1) 5) 具有:进程 ID,需要:窗口句柄 解决方案:EnumWindows(),然后在回调函数中执行 3) 并检查它是否与您的进程 ID 匹配。 6) 具有:进程句柄,需要:窗口句柄 解决方案:2)然后5)

所以你在案例6中。 如果没有窗口句柄的进程ID与您的shExInfo.hProcess的进程ID匹配,则shExInfo.hProcess不拥有任何窗口