调用应用程序或exe的方式有多种,分别是system()、ShellExecute()、WinExec()以及
CreateProcess()实现,其中首选createProcess函数,他们的使用复杂度为system() < WinExec() < ShellExecute() < CreateProcess()。
1.system
system("test.bat");//当bat文件与项目目录不同时,需要加路径
system("a.exe");
2.WinExec
winexec() 只用于可执行文件,是一个老函数,虽然使用方便,但不推荐(兼容性也不好)
WinExec("RunSimulation.bat",SW_HIDE);//应该需要当前进程等待
3.ShellExecute
ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。
ShellExecute命令虽已过时但易于得到。该命令向命令解释程序提出打开、浏览或打印文档或文件夹的请求,虽然可以用 ShellExecute运行程序,但通常只发送文档名,而命令解释程序则决定要运行那个程序。另外在打开目录文件夹时,ShellExecute命令非 常有用。
ShellExecute(NULL, _T("open"), _T("test.bat"), NULL, NULL, SW_SHOWNA);
//函数原型
ShellExecute(
hWnd: HWND; {指定父窗口句柄}
Operation: PChar; {指定动作, 譬如: open、runas、print、edit、explore、find [2] }
FileName: PChar; {指定要打开的文件或程序}
Parameters: PChar; {给要打开的程序指定参数; 如果打开的是文件这里应该是 nil}
Directory: PChar; {缺省目录}
ShowCmd: Integer {打开选项}
): HINST;
调用外部exe的测试例子
CString cstrExeDir = GetModuleDir();
cstrExeDir += _T("\\");
ShellExecute(NULL,_T("open"),cstrExeDir,NULL,NULL, SW_HIDE );
//打开指定exe程序
SHELLEXECUTEINFO ShExecInfo;
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = _T("open");
//输入要调用的exe文件路径
ShExecInfo.lpFile = _T("SwitchPortTool.exe");
//传入命令行参数数据
ShExecInfo.lpParameters =NULL; //若没有命令行参数,可为NULL
ShExecInfo.lpDirectory = cstrExeDir;//这里exe的目录可忽略,写为NULL
ShExecInfo.nShow = SW_SHOW;//这里设置为不显示exe界面,若设置为SW_SHOW,则可以显示exe界面
ShExecInfo.hInstApp = NULL;
//调用exe程序
if (!ShellExecuteEx(&ShExecInfo))
{
return false;
}
//关闭该exe程序
if( ShExecInfo.hProcess != NULL)
{
//等待程序运行完毕
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
//关闭程序
TerminateProcess(ShExecInfo.hProcess,0);
ShExecInfo.hProcess = NULL;
}
else
{
return false;
}
4.CreateProcess
WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件。该函数使用起来比较复杂,但是得到新进程的全部信息,易于修改和控制,应用场景更加灵活。
注:CreateProcess函数用来运行一个新程序。WinExec和LoadModule函数依旧可用,但是它们同样通过调用CreateProcess函数实现。
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD dwExitCode;
if (CreateProcess(L"RUN_TEST.bat",// RUN_TEST.bat位于工程所在目录下
NULL,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,// 这里不为该进程创建一个控制台窗口
NULL,
NULL,
&si, &pi))//把主进程暂停,等待子进程终止
{
WaitForSingleObject(pi.hProcess, INFINITE);// 等待bat执行结束
//GetExitCodeProcess(pi.hProcess, &dwExitCode);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
函数原型
BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
在上述参数中,参数lpStartupInfo是STARTUPINFO结构。可以用来设置控台的
标题,新窗口的的初始大小和位置,及重定向标准输入 和输出。新程序通常可以
忽略多数这些数据项,如果选择那样做的话。可以规定该结构体中的标志,已表明
要设置的数据段。有时,不想设置任何信息,也必须传递 一个有效的指针给空结
构(确定设置大小到cb,及设置dwFlags成员为0)。参数lpProcessInformation返
回进程和线程句柄,还包 括进程和线程ID。这些句柄拥有在参数
lpProcessAttributes和lpThreadAttributes中规定的访问。