я использую 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) ЕСТЬ: ИД процесса, НУЖНО: дескриптор процесса Решение: OpenProcess () 2) ИМЕЮТ: Ручка процесса, НЕОБХОДИМОСТЬ: Идентификатор процесса Решение: GetProcessId () 3) ЕСТЬ: Оконная ручка, НЕОБХОДИМОСТЬ: Идентификатор процесса Решение: GetWindowThreadProcessId () 4) ЕСТЬ: Ручка окна, НУЖНА: Ручка процесса Решение: используйте 3), а затем 1) 5) ЕСТЬ: ID процесса, НУЖНО: дескриптор окна Решение: EnumWindows (), затем в функции обратного вызова сделайте 3) и проверьте, соответствует ли он вашему идентификатору процесса. 6) ИМЕЮТ: Ручка процесса, НУЖНА: Ручка окна Решение: 2), а затем 5)
так что вы в случае 6. тогда, если ни один идентификатор процесса дескриптора окна не сопоставлен с идентификатором процесса вашего shExInfo.hProcess, то shExInfo.hProcess не имеет окна