三个SDK函数( WinExec、ShellExec、CrateProcess )的语法:
WinExec
这个函数最简单,只有两个参数,原型如下:
UINT WinExec(
LPCSTR lpCmdLine, // 命令路径
UINTuCmdShow// 显示方式
;
两个参数,前一个指定路径,后一个指定显示方式如SW_SHOW,SW_MAXIMIZE,SW_HIDE等。
使用方法如下:
WinExec("Notepad.exe", SW_SHOW); //打开记事本
WinExec("D:\Program Files\Test\Test.exe",SW_SHOWMAXIMIZED); //以最大化的方式打开Test.exe
需要注意的是若用 SW_SHOWMAXMIZED 方式去加载一个无最大化按钮的程序,譬如Neterm,Calc等等,就不会出现正常的窗体,但是已经被加到任务列表里了。
ShellExecute
原型如下:
HINSTANCE ShellExecute(
HWNDhwnd,//父窗口句柄
LPCTSTR lpOperation, //操作, 打开方式"edit","explore","open","find","print","NULL"
LPCTSTRlpFile,//文件名,前面可加路径
LPCTSTR lpParameters, //参数
LPCTSTRlpDirectory,//默认文件夹
INTnShowCmd//显示方式
);
最后的那个参数,为窗口指定可视性方面的一个命令。
请用下述任何一个常数
SW_HIDE隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE最小化窗口,活动状态给令一个窗口
SW_RESTORE用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED最大化窗口,并将其激活
SW_SHOWMINIMIZED最小化窗口,并将其激活
SW_SHOWMINNOACTIVE最小化一个窗口,同时不改变活动窗口
SW_SHOWNA用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL与SW_RESTORE相同
使用方法如下:
ShellExecute(NULL,"open","C:\Test.txt",NULL,NULL,SW_SHOWNORMAL);// 打开C:Test.txt 文件
ShellExecute(NULL, "open", "http://www.google.com",/NULL, NULL, SW_SHOWNORMAL); // 打开网页www.google.com
ShellExecute(NULL,"explore", "D:\C++",NULL,NULL,SW_SHOWNORMAL); //打开目录D:C++
ShellExecute(NULL,"print","C:\Test.txt",NULL,NULL, SW_HIDE); //打印文件C:Test.txt
ShellExecute不支持定向输出。
ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。
如果将FileName参数设置为“http:”协议格式,那么该函数将打开默认浏览器并链接到指定的URL地址。若用户机器中安装了多个浏览器,则该函数将根据Windows9x/NT注册表中http协议处理程序(ProtocolsHandler)的设置确定启动哪个浏览器。
格式一:C++用法,唯一能开一个新窗口显示网页的方法
如:ShellExecuteA(NULL,NULL,"IEXPLORE.EXE",argv[1],NULL,SW_SHOWDEFAULT);
格式二:http://网站域名/网页文件名。
如:ShellExecute(handle,‘open’,http://;www.neu.edu.cn/default.htm’,nil,nil,SW_SHOWNORMAL);
格式二:http://网站域名/网页文件名。
如:ShellExecute(handle,‘open’,http://;www.neu.edu.cn’,nil,nil,SW_SHOWNORMAL);
如果将FileName参数设置为“mailto:”协议格式,那么该函数将启动默认邮件客户程序,如MicrosoftOutlook(也包括MicrosoftOutlookExpress)或NetscapeMessanger。若用户机器中安装了多个邮件客户程序,则该函数将根据Windows9x/NT注册表中mailto协议处理程序的设置确定启动哪个邮件客户程序。
格式一:mailto:
如:ShellExecute(handle,‘open’,‘mailto:’,nil,nil,SW_SHOWNORMAL);打开新邮件窗口。
格式二:mailto:用户账号@邮件服务器地址
如:ShellExecute(handle,‘open’,‘mailto:who@mail.neu.edu.cn’,nil,nil,SW_SHOWNORMAL);打开新邮件窗口,并自动填入收件人地址。若指定多个收件人地址,则收件人地址之间必须用分号或逗号分隔开(下同)。
格式三:mailto:用户账号@邮件服务器地址?subject=邮件主题&body=邮件正文
如:ShellExecute(handle,‘open’,‘mailto:who@mail.neu.edu.cn?subject=Hello&Body=Thisisatest’,nil,nil,SW_SHOWNORMAL);打开新邮件窗口,并自动填入收件人地址、邮件主题和邮件正文。若邮件正文包括多行文本,则必须在每行文本之间加入换行转义字符%0a。
CreateProcess
原型如下:
BOOL CreateProcess(
LPCTSTR lpApplicationName, //执行程序名
LPTSTR lpCommandLine, // 参数行
//下面两个参数描述了所创建的进程和线程的安全属性,如果为NULL则使用默认的安全属性
LPSECURITY_ATTRIBUTES lpProcessAttributes, //process security attributes
LPSECURITY_ATTRIBUTESlpThreadAttributes, // threadsecurity attributes
BOOL bInheritHandles, // 继承标志
DWORD dwCreationFlags, // 创建标志
LPVOID lpEnvironment, // 环境变量
LPCTSTR lpCurrentDirectory, //初始目录
LPSTARTUPINFO lpStartupInfo, //用于在创建子进程时设置各种属性
LPPROCESS_INFORMATION lpProcessInformation //用于在进程创建后接受相关信息
;
使用方法如下:
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
si.wShowWindow=SW_SHOW;
si.dwFlags=STARTF_USESHOWWINDOW;
boolfRet=CreateProcess("D:\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,&pi);
可以看出,通过上面的几个不同的方法,都可以实现在应用程序中打开其他应用程序的目的,其中有些方法可能会麻烦一点,所以就需要我们根据不同的目的去选择最适合自己的方法去实现自己的目的!
关于三个SDK函数: WinExec,ShellExecute,CreateProcess 的其他注意事项:
1、定义头文件
在头文件stdafx.h中必须定义以下两个头文件:
#include <shlobj.h> // 可替换为windows.h
#include <shellapi.h>
如果定义了头文件 #include <windows.h>的话就不必定义#include <shlobj.h>了,"windows.h"不光是包含了"shellapi.h",它还定义了许多数据类型,如果没有这些数据类型,shellapi.h本身会出错。
2、定义路径
C++中所表示的路径要用 " \ "而不是平常所用的" ",所以以上三个函数表示路径都为:
Disk:\Directory\...\File name
WinExec("D:\ProgramFiles\Test\Test.exe",SW_SHOWMAXIMIZED);
ShellExecute(NULL,"open","C:\Test.txt",NULL,NULL,SW_SHOWNORMAL);
boolfRet=CreateProcess("D:\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,&pi);
3、程序启动错误。例如我们需要启动程序A,而程序A需要调用dat、ini等数据及配置文件,此时只能使用ShellExecute,CreateProcess并且一定要指定参数中的文件路径。
例如:ShellExecute(NULL,"open","D:\Program Files\推箱子\BoxMan.exe",NULL,"D:\ProgramFiles\推箱子\",SW_SHOWNORMAL);
4、有时需要等待程序执行完成后进行其他操作,例如程序A,要载入数据文件,程序B要读取文件,此时程序B
只能等程序A执行完操作才能开启,由于不是一个进程,不能用多线程,不过理念是一样的就是调用WaitForSingleObject()。例程如下:
void Fun()
{
char szCommandLine[256]="D:\ProgramFiles\推箱子\BoxMan.exe";//执行文件路径
STARTUPINFOsi={sizeof(si)}; //
PROCESS_INFORMATIONpi; //
BOOLsuccess;
success=::CreateProcess(NULL,szCommandLine,NULL,NULL,FALSE,0,NULL,"D:\Program Files\推箱子\",&si,&pi);
if(success==FALSE)
AfxMessageBox("打开文件失败!");
else
{
AfxMessageBox("开启程序成功!");
HANDLEhProcess=pi.hProcess;//获得开启进出那个HANDLE
DWORDdw=::WaitForSingleObject(hProcess,INFINITE);//调用WaitForSingleObject等待事件
//如果notepad结束,将发出信号。
switch(dw){
caseWAIT_OBJECT_0:
AfxMessageBox("程序关闭");
break;
caseWAIT_TIMEOUT:
AfxMessageBox("超时");
break;
caseWAIT_FAILED:
AfxMessageBox("失败");
break;
}
}
}