有3个函数可以使用:WinExec、ShellExecute、CreateProcess
1、WinExec
这个函数最简单,只有两个参数,原型如下:
UINT WinExec(
LPCSTR lpCmdLine,
UINT uCmdShow
);
lpCmdLine:指向一个空结束的字符串,串中包含将要执行的应用程序的命令行(文件名加上可选参数)。
uCmdShow:定义Windows应用程序的窗口如何显示:SW_HIDE、SW_MINIMIZE、SW_RESTORE、SW_SHOW、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED、SW_SHOWMINNOACTIVE、SW_SHOWNA、SW_SHOWNOACTIVATE、SW_SHOWNORMAL;
返回值:
若函数调用成功,则返回值大于31。若函数调用失败,则返回值为下列之一:
① 0:系统内存或资源已耗尽。
② ERROR_BAD_FORMAT:EXE文件无效(非Win32.EXE或.EXE影像错误)。
③ ERROR_FILE_NOT_FOUND:指定的文件未找到。
④ ERROR_PATH_NOT_FOUND:指定的路径未找到。
虽然Microsoft认为WinExec已过时,但是在许多时候,简单的WinExec函数仍是运行新程序的最好方式。简单地传送作为第一个参数的命令行,还需要决定如何显示程序(该程序也许会忽视它)的第二个参数。WinExec不允许用CreateProcess获得的所有选项,而它的确简单。
使用方法如下:
WinExec(_T("D:\Program Files\abc\abc.exe"),SW_SHOWMAXIMIZED);
WinExec("Notepad.exe", SW_SHOW); // 打开记事本
WinExec("D:/Program Files/01/01.exe",SW_SHOWMAXIMIZED);
需要注意的是若用 SW_SHOWMAXMIZED 方式去加载一个无最大化按钮的程序,譬如Neterm,Calc 等等,就不会出现正常的 窗体,但是已经被加到任务列表里了。
2、ShellExecute
ShellExecute比WinExex灵活一点,所以参数就要多一点,原型如下:
HINSTANCE ShellExecute(
HWND hwnd, //父窗口句柄
LPCTSTR lpOperation,//打开方式
LPCTSTR lpFile, //待打开的文件名,前面可加路径
LPCTSTR lpParameters, //参数
LPCTSTR lpDirectory, //默认文件路径
INT nShowCmd //显示方式
);
hwnd:指向父窗口的窗口句柄。此窗口接收应用程序产生的任何信息框。
lpOperation:此字符串指定要执行的操作:
"open" 此函数打开由参数lpFile指定的文件,此文件可以是一个可执行文件或文档文件,也可是一个文件夹。
"print" 此函数打印由参数lpFile指定的文件,此文件应是一个文档文件,假如此文件是一个可执行文件,则打开此文件。
"explore" 此函数搜索由参数lpFile指定的文件夹,此文件应是一个文档文件,
此参数可以为空。这种情况下,函数默认用于打开"open"由参数lpFile指定的文件。
lpFile:指定要打开或打印的文件或者是要打开或搜索的文件夹。
lpParameters:假如参数lpFile指定一个可执行文件,lpParameters指定要传递给应用程序的参数。假如lpFile指定一个文档文件,lpParameters应为空。
lpDirectory:指定默认目录。
nShowCmd:假如lpFile指定一个可执行文件,nShowCmd表明应用程序打开时如何显示。假如lpFile指定一个文档文件,nShowCmd应为空。
返回值:
若函数调用成功,则返回值大于32,否则为一个小于等于32的错误值。
使用方法:
ShellExecute(NULL,_T("open"),_T("abc.exe"),NULL,_T("D:\Program Files\abc\"),SW_SHOWNORMAL);
ShellExecute(NULL, ''open'', ''c:\test\readme.txt'', nll, nll, SW_SHOW);
ShellExecute(NULL,"explore", "D:/C++",NULL,NULL,SW_SHOWNORMAL); // 打开目录D:/C++
ShellExecute(NULL,"print","C:/Test.txt",NULL,NULL, SW_HIDE); // 打印文件C:/Test.txt
ShellExecuteEx:这个windows函数用的不多,但是要手动提升进程的权限时,就要用这个函数。
用法:
SHELLEXECUTEINFO sei = {sizeof(SHELLEXECUTEINFO)};
sei.lpVerb = TEXT("runas"); //“runas”表示使用管理员权限运行。
sei.lpFile = TEXT("abc.exe");
//sei.lpDirectory = TEXT("C:\abc");
sei.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&sei))
{
DWORD dwError = GetLastError();
if(dwError==ERROR_CANCELLED)
{
printf("提升权限被用户拒绝 ");
}
else if(dwError==ERROR_FILE_NOT_FOUND)
{
printf("所要执行的文件没有找到 ");
}
}
3、CreateProcess
BOOL CreateProcess(
LPCTSTR lpApplicationName, //执行程序名
LPTSTR lpCommandLine, // 参数行
//下面两个参数描述了所创建的进程和线程的安全属性,如果为NULL则使用默认的安全属性
LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread security attributes
BOOL bInheritHandles, // 继承标志
DWORD dwCreationFlags, // 创建标志
LPVOID lpEnvironment, // 环境变量
LPCTSTR lpCurrentDirectory, // 运行该进程的初始目录
LPSTARTUPINFO lpStartupInfo, // 用于在创建子进程时设置各种属性
LPPROCESS_INFORMATION lpProcessInformation //用于在进程创建后接受相关信息
);
lpApplicationName:指定了要执行的模块
lpCommandLine:定义了要执行的命令行。
lpProcessAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。
lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子线程继承。
bInheritHandles,:表明新进程是否从调用进程继承句柄。
dwCreationFlags:定义控制优先类和进程创建的附加标志。
lpEnvironment:指向一个新进程的环境块。
lpCurrentDirectory:定义了子进程的当前驱动器和当前目录。
lpStartupInfo:指向一个STARTUPINFO结构,该结构定义了新进程的主窗口将如何显示。
lpProcessInformation:指向PROCESS_INFORMATION结构,该结构接受关于新进程的表示信息。
在上面的参数中,使用了两个比较重要的数据结构:STARTUPINFO和PROCESS_INFORMATION。这两个结构的定义分别如下:
typedef struct _STARTUPINFO { // si
DWORD cb; //结构长度
LPTSTR lpReserved; //保留
LPTSTR lpDesktop; //保留
LPTSTR lpTitle; //如果为控制台进程则为显示的标题
DWORD dwX; //窗口横坐标
DWORD dwY; //窗口丛坐标
DWORD dwXSize; //窗口宽度
DWORD dwYSize; //窗口高度
DWORD dwXCountChars; //控制台窗口字符号宽度
DWORD dwYCountChars; //控制台窗口字符号高度
DWORD dwFillAttribute; //控制台窗口填充模式
DWORD dwFlags; //创建标记
WORD wShowWindow; //窗口显示标记,如同ShowWindow中的标记
WORD cbReserved2; //保留参数
LPBYTE lpReserved2; //保留参数
HANDLE hStdInput; //标准输入句柄
HANDLE hStdOutput; //标准输出句柄
HANDLE hStdError; //标准错误句柄
} STARTUPINFO, *LPSTARTUPINFO;
typedef struct _PROCESS_INFORMATION { // pi
HANDLE hProcess; //进程句柄
HANDLE hThread; //进程的主线程句柄
DWORD dwProcessId; //进程的ID
DWORD dwThreadId; //进程的主线程ID
} PROCESS_INFORMATION;
在上述参数中,参数lpStartupInfo是STARTUPINFO结构。可以用来设置控制台的标题,新窗口的的初始大小和位置,及重定向标准输入和输出。参数lpProcessInformation返回进程和线程句柄,还包括进程和线程ID。这些句柄须拥有在参数lpProcessAttributes和lpThreadAttributes中规定的访问权。
返回值:
若函数调用成功,则返回值不为0;若函数调用失败,返回值为0。
使用方法:
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
si.wShowWindow=SW_SHOW;
si.dwFlags=STARTF_USESHOWWINDOW;
bool fRet=CreateProcess("D:\Program Files\abc\abc.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);