如何打开一个程序或创建一个进程

打开一个程序和创建一个进程基本上是同一个意思。我们的工具箱里面有几个函数备选:
system, WinExec, ShellExecuteEx, CreateProcess,他们有以下几点不同:
- 只有system是同步操作。
- 只有ShellExecuteEx, CreateProcess支持Unicode。
- 是否打开新的Console窗口: 只在父子都是console下有效
   system,WinExec总是不会打开。ShellExecuteEx,CreateProcess则可以控制是否打开新Console窗口
- 是否显示:在父子至少有一个不是console的情况下有效。

[system]
system是在简单的可怜,只需传入一个命令行。
system( "notepad C://boot.ini" );


[WinExec]
WinExec比之system能够控制目标窗口显示与否。
WinExec( "notepad C://boot.ini", SW_SHOW );
WinExec( "/"C://WINDOWS//system32//notepad.exe/" C://boot.ini", 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 ) );
info.cbSize = sizeof( info );
// SEE_MASK_NOCLOSEPROCESS代表需要返回进程Handle
// SEE_MASK_NO_CONSOLE只在父子都是console时有作用表示不要产生新的console窗口
info.fMask = SEE_MASK_NOCLOSEPROCESS |SEE_MASK_NO_CONSOLE;
info.lpFile = _T( "notepad" ); // 注意如果没有提供路径则按下列顺序搜索文件(当前目录,系统目录,注意不包括环境变量path中的目录)
info.lpParameters = _T( "C://boot.ini" );
info.nShow = SW_SHOW;

ShellExecuteEx( &info );
// 可以进程Handle做些事情,最常见的就是等待进程结束。
WaitForSingleObject( info.hProcess, INFINITE );

 
[CreateProcess]
提供了比ShellExecuteEx更为精细的参数控制。
通常使用CreateProcess需要提供至关重要的4个参数
 - cmdLine 
 - creationFlag
 - startupInfo
 - processInfo
 
* cmdLine是你需要呼叫之process的命令行参数,比如要打开D:/test.txt, 你可以提供"notepad D://test.txt";
   值得注意的是Unicode版本的CreateProcessW要求cmdLine不能是const
* creationFlag决定如何产生目标process
 creationFlag = CREATE_NEW_CONSOLE 将在新的console产生process
 creationFlag = CREATE_NO_WINDOW 将在后台产生process
* startupInfo决定产生的process的其实信息,通常我们会设置产生process时是否显示窗口,这样做:
  startupInfo.dwFlags = STARTIF_USESHOWWINDOW;
  startupInfo.wShowWindow = 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 ) );
    startupInfo.cb = sizeof( startupInfo );
    startupInfo.dwFlags = STARTF_USESHOWWINDOW; // 使特定成员有效
    startupInfo.wShowWindow = ( WORD )showWindowOption;
    startupInfo.lpTitle = const_cast< LPWSTR >( windowTitle.GetString() );

    CString commandLine = fileName + _T( " " ) + arguments;  
   
    PROCESS_INFORMATION processInfo;
    CreateProcess(
        NULL,
        const_cast< LPWSTR >( commandLine.GetString() ),
        NULL,
        NULL,
        false,
        creationFlag,
        NULL,
        NULL,
        &startupInfo,
        &processInfo
        );   
    return processInfo.hProcess;

}

 


可以在创建进程后通过WaitForSingleObject来捕捉核心对象hProcess
当进程结束后,WaitForSingleObject(hProcess, INFINITE)返回。
当然你可以WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0来立刻检测进程是否结束。


最后一定要CloseHandle( hProcess ) 关闭进程句柄

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值