[英]How to find out if process created with ShellExecuteEx owns a window?
I'm using ShellExecuteEx
to run external application: 我正在使用
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);
}
Everything works perfectly but there exist an unplanned behaviour of this external app that after closing its main window its process is still active. 一切正常,但是此外部应用程序存在计划外的行为,即在关闭其主窗口后其进程仍处于活动状态。 This prevents
WaitForSingleObject(shExInfo.hProcess, INFINITE);
这可以防止
WaitForSingleObject(shExInfo.hProcess, INFINITE);
from returning and I have to terminate the process manualy. 从返回,我必须手动终止该过程。
Instead I'm looking for a way to replace WaitForSingleObject(shExInfo.hProcess, INFINITE);
相反,我正在寻找一种替代
WaitForSingleObject(shExInfo.hProcess, INFINITE);
with a loop that checks if external process owns a window and if not terminate it. 带有一个循环,该循环检查外部进程是否拥有窗口,如果没有则终止窗口。
This is what I thought of but if there is a better way please point it out for me. 这就是我的想法,但是如果有更好的方法,请给我指出。
UPDATE: 更新:
Thanks to Robson answer I managed to do what I intended to: 感谢Robson的回答,我设法做到了我想要做的事情:
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;
}
And my loop: 而我的循环:
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);
}
found a good answer at http://forums.codeguru.com/showthread.php?392273-RESOLVED-How-to-get-window-s-HWND-from-it-s-process-handle 在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)
so you are in case 6. then if no window handle's process ID is matched with your shExInfo.hProcess's process ID then shExInfo.hProcess owns no window 因此您处于情况6。然后,如果没有窗口句柄的进程ID与shExInfo.hProcess的进程ID匹配,则shExInfo.hProcess不拥有任何窗口
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.