启动外部应用程序并阻止当前应用程序,直到启动的应用程序退出

时间:2010-07-09 03:37:30

标签: c++ visual-c++ mfc

我不确定是否有办法

启动外部应用程序,并阻止当前应用程序,直到启动的应用程序退出。

目前,我正在使用以下非阻塞方法(MFC)来启动

std::string str = "Notepad2.exe";
// Non-blocking. Return immediately.
WinExec(str.c_str(), SW_SHOW);

3 个答案:

答案 0 :(得分:1)

代码:

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

正如Jerry所指出的,这对你自己的GUI来说是不好的。但是,如果您直接或间接启动的进程执行广播SendMessage,那么这可能会导致灾难性的死锁,因为您的进程有一个窗口但没有抽取任何消息:启动的进程正在等待您的代码处理其消息,并且你在等它。铛...

您可以使用MsgWaitForMultipleObjects,或者更好的是,将启动和等待关闭拆分为一个线程,并简单地禁用您不希望用户与之交互的UI的任何部分。

答案 1 :(得分:0)

带有ShellExecuteEx

SEE_MASK_NOCLOSEPROCESS(除其他外)将为您提供新流程的处理方式。您可以在该句柄上执行WaitForSingleObject,该句柄将在终止时发出信号。顺便说一下,对于一个GUI程序,这几乎总是一个坏主意 - 让你的GUI没有响应,直到另一个程序退出是一个糟糕的主意。

答案 2 :(得分:0)

如果您只是想启动流程,则不必使用ShellExecuteEx,而是使用CreateProcess。这是一个未经测试的例子:

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);