ShellExecuteEx
with SEE_MASK_NOCLOSEPROCESS
will (among other things) give you a handle to the new process. You can do a WaitForSingleObject
on that handle, which will be signaled when it terminates. BTW, for a GUI program, this is almost always a bad idea -- making your GUI unresponsive until another program exits is really a poor idea.
views:
64answers:
3
A:
Jerry Coffin
2010-07-09 03:59:52
A:
code:
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof (SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = "open";
sei.lpFile = "notepad.exe";
sei.nShow = SW_SHOWNORMAL;
if (ShellExecuteEx (&sei))
{
WaitForSingleObject (sei.hProcess, INFINITE);
}
As Jerry points out, this is bad for your own GUI. But if the process you launch, directly or indirectly, does a broadcast SendMessage then this can cause catastrophic deadlock, because your process has a window but isn't pumping any messages: the launched process is waiting for your code to handle its message, and you're waiting for it. Clang...
You could use MsgWaitForMultipleObjects instead, or better still, split the launch-and-wait off into a thread and simply disable any part of your UI you don't want the user to interact with.
Bob Moore
2010-07-09 12:00:54
A:
If you just want to launch a process, you don't have to use ShellExecuteEx
, use CreateProcess
instead. Here is an untested example:
std::wstring commandLine = L"Notepad2.exe"
std::wstring::size_type length = commandLine.size();
boost::scoped_array<WCHAR> buffer(new WCHAR[length + 1]);
std::copy(commandLine.begin(), commandLine.end(), buffer.get());
buffer[length] = L'\0';
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof startupInfo);
startupInfo.cb = sizeof startupInfo;
PROCESS_INFORMATION processInfo;
CreateProcess(NULL, buffer.get(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo);
CloseHandle(processInfo.hThread);
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
Philipp
2010-07-09 12:13:47