打开一个程序和创建一个进程基本上是同一个意思。我们的工具箱里面有几个函数备选:
system, WinExec, ShellExecuteEx, CreateProcess,他们有以下几点不同:
- 只有system是同步操作。
- 只有ShellExecuteEx, CreateProcess支持Unicode。
- 是否打开新的Console窗口: 只在父子都是console下有效
system,WinExec总是不会打开。ShellExecuteEx,CreateProcess则可以控制是否打开新Console窗口
- 是否显示:在父子至少有一个不是console的情况下有效。
[system]
system是在简单的可怜,只需传入一个命令行。
system( "notepad C://" );
[WinExec]
WinExec比之system能够控制目标窗口显示与否。
WinExec( "notepad C://", SW_SHOW );
WinExec( "/"C://WINDOWS//system32///" C://", SW_HIDE );
cout << "xx" << endl;
WinExec( "taskkill", SW_HIDE );
cout << "xx" << endl; // 这个xx会先于taskkill的内容显示(因为创建进程是异步的,并且不会很快)
[ShellExecuteEx]
WinExec最大的缺陷是不支持宽字符,你无法找到WinExecW。另外你无法针对你打开的程序做进一步的操作,比如等待程序结束等。
如果你有这些需要,就应该使用ShellExecuteEx。
需要做的配置一个SHELLEXECUTEINFO结构,该结构描述如何打开以及打开什么样的程序。然后以ShellExecuteEx调用之。
SHELLEXECUTEINFO info;
ZeroMemory( &info, sizeof( info ) );
= sizeof( info );
// SEE_MASK_NOCLOSEPROCESS代表需要返回进程Handle
// SEE_MASK_NO_CONSOLE只在父子都是console时有作用,表示不要产生新的console窗口。
= SEE_MASK_NOCLOSEPROCESS |SEE_MASK_NO_CONSOLE;
= _T( "notepad" ); // 注意如果没有提供路径则按下列顺序搜索文件(当前目录,系统目录,注意不包括环境变量path中的目录)
= _T( "C://" );
= SW_SHOW;
ShellExecuteEx( &info );
// 可以进程Handle做些事情,最常见的就是等待进程结束。
WaitForSingleObject( , INFINITE );
[CreateProcess]
提供了比ShellExecuteEx更为精细的参数控制。
通常使用CreateProcess需要提供至关重要的4个参数
- cmdLine
- creationFlag
- startupInfo
- processInfo
* cmdLine是你需要呼叫之process的命令行参数,比如要打开D:/, 你可以提供"notepad D://";
值得注意的是Unicode版本的CreateProcessW要求cmdLine不能是const
* creationFlag决定如何产生目标process
creationFlag = CREATE_NEW_CONSOLE 将在新的console产生process
creationFlag = CREATE_NO_WINDOW 将在后台产生process
* startupInfo决定产生的process的其实信息,通常我们会设置产生process时是否显示窗口,这样做:
= STARTIF_USESHOWWINDOW;
= SW_SHOW; // SW_HIDE(表示在后台运作,与creationFlag呼应)
* processInfo则是个输出参数,目标进程创建成功后,此输出参数将包含进程相关信息。
下面是一个典型的示例
HANDLE ExecuteFile( const CString& fileName, const CString& arguments,
DWORD showWindowOption,
const CString& windowTitle )
{
DWORD creationFlag = 0;
STARTUPINFO startupInfo;
ZeroMemory( &startupInfo, sizeof( startupInfo ) );
= sizeof( startupInfo );
= STARTF_USESHOWWINDOW; // 使特定成员有效
= ( WORD )showWindowOption;
= const_cast< LPWSTR >( () );
CString commandLine = fileName + _T( " " ) + arguments;
PROCESS_INFORMATION processInfo;
CreateProcess(
NULL,
const_cast< LPWSTR >( () ),
NULL,
NULL,
false,
creationFlag,
NULL,
NULL,
&startupInfo,
&processInfo
);
return ;
}
可以在创建进程后通过WaitForSingleObject来捕捉核心对象hProcess
当进程结束后,WaitForSingleObject(hProcess, INFINITE)返回。
当然你可以WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0来立刻检测进程是否结束。
最后一定要CloseHandle( hProcess ) 关闭进程句柄