C++程序中调⽤exe可执⾏⽂件
在开发项⽬的时候,有的时候会分开来开发,分开的有时是exe⽂件,有的时候也会调⽤现成的⼯具包⾥⾯的⼀些exe⽂件,这样在项⽬⾥⾯就要通过调⽤exe⽂件来使⽤。
那么在C++⾥⾯直接调⽤exe⽂件的⽅法有哪些呢?现在可考虑的⽅法主要有:
a.使⽤system函数
b.使⽤exec或者是execv函数
c.使⽤WinExec函数
d.使⽤CreateProcess函数
e.使⽤ShellExcecuteEx函数
1)上⾯的5中⽅法中,system函数,函数原型system(执⾏shell命令)定义函数是,int system(const char * string),可以调⽤⼀些DOS命令,⽐如:
system("cls");//清屏,等于在DOS上使⽤cls命令
system函数会调⽤fork()函数产⽣⼦进⾏横,由⼦进程来调⽤/bin/sh-c string来执⾏参数string字符串所代表的命令,此命令执⾏完后随即返回调⽤的进程,system函数不能控制程序窗⼝是否显⽰。⼀般在项⽬中,这种⽅法不予考虑。
2)使⽤execl或execv函数
这是exec函数族⾥⾯的两个函数,在UNIX环境下⽤的⽐较多,exec函数族的作⽤是根据指定的⽂件名到可执⾏⽂件,并⽤它来取代调⽤进程的内容,也就是说在调⽤进程内部执⾏⼀个可执⾏⽂件,这⾥的可执⾏⽂件既可以是⼆进制⽂件,也可以是任何下的可执⾏的脚本⽂件,与⼀般情况不同,exec函数族的函数执⾏成功后不会返回,只有调⽤失败了才会返回⼀个-1,从原程序的调⽤点接着往下执⾏。它也是不能控制程序窗⼝是否显⽰。
3)使⽤WinExec函数
WinExec函数可以⽅便地在应⽤程序中执⾏⼀个程序,执⾏⼀个标准程序⼀般使⽤:
WinExec('C:\WINDOWS\NOTEPAD.EXE', SW_SHOWNORMAL);
第⼆个参数是控制程序主窗⼝的显⽰⽅式,⽤WinExec只能执⾏exe⽂件,但是WinExec函数不好控制主程序来等该exe程序的结束。WinExec是Windows的⽼函数了,现在的CreateProcess⼏乎可以替代
WinExe的所有功能。
4)使⽤CreateProcess函数
CreateProcess函数是新建⼀个进程,下⾯是⼀个使⽤CreateProcess函数的例⼦:
void createchildprocessandwaituntildone(const ansistring& strcmdline)
{
process_information piprocinfo;
startupinfo sistartinfo;
// set up members of startupinfo structure.
sistartinfo.cb = sizeof(startupinfo);
sistartinfo.lpreserved = null;
sistartinfo.lpreserved2 = null;
sistartinfo.cbreserved2 = 0;
sistartinfo.lpdesktop = null;
sistartinfo.dwflags = 0;
// create the child process.
createprocess(
null,
strcmdline.c_str(),
null, // process security attributes
null, // primary thread security attributes
0, // handles are inherited
0, // creation flags
null, // use parent\'s environment
null, // use parent\'s current directory
&sistartinfo, // startupinfo pointer
&piprocinfo); // receives process_information
// wait for the processs to finish
dword rc = waitforsingleobject(
piprocinfo.hprocess, // process handle
infinite);
}
使⽤CreateProcess函数,你必须⼈为地控制该进程的⽣死,这⼀⽅⾯是使⽤进程控制来实现。进程控制的意义在于可以创建⼀个进程,并且可以通过进程句柄结束进程。
5)使⽤ShellExcecuteEx函数
这个函数主要是在⽂件上执⾏⼀个函数,如果执⾏成功则返回⼀个⾮0值,否则返回⼀个0值。函数的原型是:
WINSHELLAPI BOOL WINAPI ShellExecuteEx(
LPSHELLEXECUTEINFO lpExecInfo);
参数lpExecInfo:是 LPSHELLEXECUTEINFO 的地址,包含了和接收⼀些被执⾏的应⽤程序的⼀些信息。下⾯是⼀个使⽤的⽰例:
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = _T("open");
ShExecInfo.lpFile = _T("a.exe");
ShExecInfo.lpParameters = _T("-a a");
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
AfxGetApp()->BeginWaitCursor();
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
AfxGetApp()->EndWaitCursor();
这个函数可以通过ShExecInfo.lpParameters来传递exe⽂件的参数,通过属性ShExecInfo.nShow来控制程序窗⼝是否显⽰。
后⾯三个函数都是SDK函数,现在在执⾏项⽬中的exe⽂件的时候,使⽤⽐较多的就是后⾯得两个函数,我在⾃⼰的项⽬中使⽤的就是ShellExecuteEx函数,⽐CreateProcess函数使⽤⽅便⼀些。
VC中调⽤其他可执⾏程序,就我⽬前所知有三种⽅法:
1. HINSTANCE ShellExecute(HWND hwnd,    LPCTSTR lpVerb,LPCTSTR lpFile,LPCTSTR lpParameters,LPCTSTR lpDirectory,INT nShowCmd);
特殊需要讲的参数:
lpVerb:对lpFile要执⾏的⾏为,包括"open","explore","print","edit","find","properties"
lpFile:要操作的对象
lpParameters:传递给为lpFile的参数
nShowCmd:窗⼝的显⽰参数,不显⽰(SW_HIDE)
注意:返回值如果⼩于32,则是错误,见具体错误
其扩展函数ShellExecuteEx功能更全
此函数声明包含在头⽂件shellapi.h,库是shell32.lib
2. UINT WinExec(
LPCSTR,  // command line
UINT          // window style
);
参数lpCmdLine为⽂件名+参数
如果执⾏正确,返回值⼤于31
声明在头⽂件windows.h,包含在kernel32.lib中
3. BOOL CreateProcess(
LPCTSTR,                // name of executable module
LPTSTR,                      // command line string
LPSECURITY_ATTRIBUTES, // SD
LPSECURITY_ATTRIBUTES,  // SD
BOOL,                      // handle inheritance option
createprocessa
DWORD,                    // creation flags
LPVOID,                      // new environment block
LPCTSTR,                // current directory name
LPSTARTUPINFO,// startup information
LPPROCESS_INFORMATION // process information
);
这个够复杂,启动⼀个进程的⽅式打开⼀个程序。声明所在的头⽂件和库同WinExec
以上三种⽅法,推荐使⽤第⼀种。第⼆种不推荐使⽤,因为它存在只是为了⽀持16位机的。
还需要考虑另外⼀个问题,就是后⾯程序的执⾏,可能需要等待这个进程结束之后才能执⾏,⽽不能两个进程并发执⾏。(两个进程⼀个是原进程,⼀个是启动的进程)。参考了:wwwblogs/del/archive/2008/02/13/1067871.html
可以如下使⽤:
HANDLE hProg;
hProg=ShellExecute(NULL, "open", "", NULL, NULL, SW_HIDE);
WaitForSingleObject(hProg, INIFINTE);
在我使⽤的时候是要⽤⼀个MFC程序打开⼀个控制台程序,控制台程序执⾏结果写⼊到⼀个⽂档中,然后再⽤mfc程序读出。(为什么这么⿇烦,是因为控制台程序⽤到的库是第三⽅库,不⽀持MFC,没办法)。
在控制台程序结束时,写的⽂件未必已经写完,并关闭了。所以还需要额外做些⼯作。
While(!FileExists(Result.TXT)) ;
READFile(Result.TXT);
注意while语句后⾯的";"
ShellExecute:
1.函数功能:
你可以给它任何⽂件的名字,它都能识别出来并打开它。
2.函数原型:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
3.参数说明:
hwnd:
⽤于指定⽗窗⼝句柄。当函数调⽤过程出现错误时,它将作为Windows消息窗⼝的⽗窗⼝。
lpOperation:
⽤于指定要进⾏的操作。
“open”操作表⽰执⾏由lpFile参数指定的程序,或打开由lpFile参数指定的⽂件或⽂件夹;
“print”操作表⽰打印由lpFile参数指定的⽂件;
“explore”操作表⽰浏览由lpFile参数指定的⽂件夹。
当参数设为NULL时,表⽰执⾏默认操作“open”。
lpFile:
⽤于指定要打开的⽂件名、要执⾏的程序⽂件名或要浏览的⽂件夹名。
lpParameters:
若lpFile参数是⼀个可执⾏程序,则此参数指定命令⾏参数,否则此参数应为NULL.
lpDirectory:
⽤于指定默认⽬录.
nShowCmd:
若lpFile参数是⼀个可执⾏程序,则此参数指定程序窗⼝的初始显⽰⽅式,否则此参数应设置为0。
这个参数常⽤的常数:
SW_HIDE 隐藏窗⼝,活动状态给令⼀个窗⼝
SW_MINIMIZE 最⼩化窗⼝,活动状态给令⼀个窗⼝
SW_RESTORE ⽤原来的⼤⼩和位置显⽰⼀个窗⼝,同时令其进⼊活动状态
SW_SHOW ⽤当前的⼤⼩和位置显⽰⼀个窗⼝,同时令其进⼊活动状态
SW_SHOWMAXIMIZED 最⼤化窗⼝,并将其激活
SW_SHOWMINIMIZED 最⼩化窗⼝,并将其激活
SW_SHOWMINNOACTIVE 最⼩化⼀个窗⼝,同时不改变活动窗⼝
SW_SHOWNA ⽤当前的⼤⼩和位置显⽰⼀个窗⼝,不改变活动窗⼝
SW_SHOWNOACTIVATE ⽤最近的⼤⼩和位置显⽰⼀个窗⼝,同时不改变活动窗⼝
SW_SHOWNORMAL 与SW_RESTORE相同
若ShellExecute函数调⽤成功,则返回值为被执⾏程序的实例句柄。若返回值⼩于32,则表⽰出现错误。
4.使⽤⽅法:
例如:
ShellExecute(NULL,"open","iloveu.bmp",NULL,NULL,SW_SHOWNORMAL);
⽤缺省的位图编辑器打开⼀个叫iloveu.bmp的位图⽂件,这个缺省的位图编辑器可能是 Microsoft Paint, Adobe Photoshop, 或者 Corel PhotoPaint。
这个函数能打开任何⽂件,甚⾄是桌⾯和URL快捷⽅式( .ink或 .url)。ShellExecute解析系统注册表HKEY_CLASSES_ROOT中所有的内容,判断启动那⼀个执⾏程序,并且启动⼀个新的实例或使⽤DDE将⽂件名连到⼀打开的实例。然后,ShellExecute 返回打开⽂件的应⽤的实例句柄。
ShellExecute(NULL, "open", "www.microsoft", NULL, NULL, SW_SHOWNORMAL);
这个代码使你能访问微软的主页。当ShellExecute遇到⽂件名前⾯的“http:”时,可以判断出要打开的⽂件是Web⽂件,随之启动Internet Explorer 或者 Netscape Navigator 或者任何你使⽤的别的浏览器打开⽂件。
ShellExecute还能识别其它协议,象FTP、GOPHER。甚⾄识别“mailto”,如果⽂件名指向“mailto:zxn@hqinfo”,它启动电⼦邮件程序并打开⼀个待编辑的新邮件,例如:ShellExecute(NULL, "open",“mailto:zxn@hqinfo”, NULL, NULL, SW_SHOWNORMAL);打开新邮件窗⼝。
总之,ShellExecute函数就是如此简单地打开磁盘⽂件和Internet⽂件。如果将第⼆个参数“OPEN”改
为“PRINT”或者“EXPLORE”,ShellExecute将能打印⽂件和打开⽂件夹。ShellExecute还有⼀个扩展函数ShellExecuteEx,所带参数中有⼀个特殊的结构,功能更强,或者任何你使⽤的别的浏览器打开⽂件。
======================================================================================
Q: 如何打开⼀个应⽤程序
ShellExecute(this->m_hWnd,"open","","","", SW_SHOW ); 或 ShellExecute(this-
>m_hWnd,"open","","c:\\MyLog.log","",SW_SHOW ); 正如您所看到的,我并没有传递程序的完整路径。
Q: 如何打开⼀个同系统程序相关连的⽂档?ShellExecute(this->m_hWnd,"open","c:\\","","",SW_SHOW );
Q: 如何打开⼀个⽹页?
ShellExecute(this->m_hWnd,"open","","","", SW_SHOW );
Q: 如何激活相关程序,发送EMAIL?
ShellExecute(this->m_hWnd,"open","mailto:nishinapp@yahoo","","", SW_SHOW );
Q: 如何⽤系统打印机打印⽂档?
ShellExecute(this->m_hWnd,"print","c:\\","","", SW_HIDE);
Q: 如何⽤系统查功能来查指定⽂件?
ShellExecute(m_hWnd,"find","d:\\nish",NULL,NULL,SW_SHOW);
Q: 如何启动⼀个程序,直到它运⾏结束?
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\";
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
或:
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c:\\winnt\\", NULL,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
else
{
MessageBox("The process could not ");
}
Q: 如何显⽰⽂件或⽂件夹的属性?
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。