您的位置:首页 > 其它

VC中如何调用其他的可执行程序

2014-06-20 15:11 525 查看

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函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,也就是说在调用进程内部执行一个可执行文件,这里的可执行文件既可以是二进制文件,也可以是任何Linux下的可执行的脚本文件,与一般情况不同,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中调用其他可执行程序,就我目前所知有三种方法:

HINSTANCE ShellExecute(HWND hwnd,     LPCTSTRlpVerb,LPCTSTRlpFile,LPCTSTRlpParameters,LPCTSTRlpDirectory,INTnShowCmd);

特殊需要讲的参数:

lpVerb:对lpFile要执行的行为,包括"open","explore","print","edit","find","properties"

lpFile:要操作的对象

lpParameters:传递给为lpFile的参数

nShowCmd:窗口的显示参数,不显示(SW_HIDE)

注意:返回值如果小于32,则是错误,见具体错误

其扩展函数ShellExecuteEx功能更全

此函数声明包含在头文件shellapi.h,库是shell32.lib

UINT WinExec(

                          LPCSTR

lpCmdLine// command line

                           UINT
uCmdShow           // window style
);

参数lpCmdLine为文件名+参数

如果执行正确,返回值大于31

声明在头文件windows.h,包含在kernel32.lib中
BOOL CreateProcess(

      LPCTSTR
lpApplicationName,                
// name of executable module

     LPTSTR
lpCommandLine,                     
// command line string

     LPSECURITY_ATTRIBUTES
lpProcessAttributes, // SD

     LPSECURITY_ATTRIBUTES
lpThreadAttributes,  // SD
      BOOL bInheritHandles,                     
// handle inheritance option

     DWORD
dwCreationFlags,                    
// creation flags

     LPVOID
lpEnvironment,                     
// new environment block
      LPCTSTR lpCurrentDirectory,               
// current directory name

     LPSTARTUPINFO
lpStartupInfo,// startup information
      LPPROCESS_INFORMATION
lpProcessInformation // process information

);
这个够复杂,启动一个进程的方式打开一个程序。声明所在的头文件和库同WinExec
以上三种方法,推荐使用第一种。第二种不推荐使用,因为它存在只是为了支持16位机的。

还需要考虑另外一个问题,就是后面程序的执行,可能需要等待这个进程结束之后才能执行,而不能两个进程并发执行。(两个进程一个是原进程,一个是启动的进程)。参考了:http://www.cnblogs.com/del/archive/2008/02/13/1067871.html

可以如下使用:

HANDLE hProg;

hProg=ShellExecute(NULL, "open", "xxx.exe", 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", "http://www.microsoft.com", NULL, NULL, SW_SHOWNORMAL);

这个代码使你能访问微软的主页。当ShellExecute遇到文件名前面的“http:”时,可以判断出要打开的文件是Web文件,随之启动Internet Explorer 或者 Netscape Navigator 或者任何你使用的别的浏览器打开文件。

ShellExecute还能识别其它协议,象FTP、GOPHER。甚至识别“mailto”,如果文件名指向“mailto:zxn@hq.cninfo.net”,它启动电子邮件程序并打开一个待编辑的新邮件,例如:
ShellExecute(NULL, "open",“mailto:zxn@hq.cninfo.net”, NULL, NULL, SW_SHOWNORMAL);打开新邮件窗口。
总之,ShellExecute函数就是如此简单地打开磁盘文件和Internet文件。如果将第二个参数“OPEN”改为“PRINT”或者“EXPLORE”,ShellExecute将能打印文件和打开文件夹。ShellExecute还有一个扩展函数ShellExecuteEx,所带参数中有一个特殊的结构,功能更强,或者任何你使用的别的浏览器打开文件。

======================================================================================

Q: 如何打开一个应用程序

ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW ); 或 ShellExecute(this->m_hWnd,"open","notepad.exe","c:\\MyLog.log","",SW_SHOW ); 正如您所看到的,我并没有传递程序的完整路径。

Q: 如何打开一个同系统程序相关连的文档?ShellExecute(this->m_hWnd,"open","c:\\abc.txt","","",SW_SHOW );

Q: 如何打开一个网页?

ShellExecute(this->m_hWnd,"open","http://www.google.com","","", SW_SHOW );

Q: 如何激活相关程序,发送EMAIL?

ShellExecute(this->m_hWnd,"open","mailto:nishinapp@yahoo.com","","", SW_SHOW );

Q: 如何用系统打印机打印文档?

ShellExecute(this->m_hWnd,"print","c:\\abc.txt","","", 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:\\MyProgram.exe";

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\\notepad.exe", 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 be started...");

}

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: