私は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);
}