C++程序中调用exe可执行文件

[本文整理自:http://blog.csdn.net/moyumoyu/article/details/6767621]

更详细的参考在vc中怎么调用exe文件并传递参数


当项目比较大的时候,通常会分开来开发,如果分开的部分只是一些函数或类,整合的时候 就可以使用静态库或动态库。但如果分开的是一个exe文件,整合的时候,就要通过调用exe文件来使用。尤其是当第三方软件是一个用c语言编写的exe文件时,更是需要如此。 

最近在我所开发的LCDS系统当中就碰到了这样的问题。他需要调用一个分类器来处理数据,而手头上的分类器是经典的C4.5决策树分类器,它是用c语言写的,没有.h头文件,生成的是一个exe文件,通过在命令行执行main函数来处理数据。如果想把其改成静态库或动态库,因为没有头文件,改写后似乎不好调用其函数,因此考虑直接调用其生成的exe文件。可考虑的方法有:

      1.使用system函数      可以参考 【 在vc6控制台程序中如何调用运行ImageMagick命令行工具
      2.使用execl或execv函数         
      3.使用WinExec函数     
      4.使用CreateProcess函数 
      5.使用ShellExecuteEx函数 
      system函数和execl、execv函数不能控制程序窗口是否显示,我要的效果是不显示该exe程序的窗口,所以这两种方法不予考虑。WinExec函数不好控制主程序来等该exe程序的结束,所以放弃。CreateProcess函数是新建一个进程,所以,你必须人为地控制该进程的生死,不如ShellExecuteEx方便,所以最终我选择的是ShellExecuteEx函数。
      程序如下: 
SHELLEXECUTEINFO ShExecInfo = {0}; 
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); 
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; 
ShExecInfo.hwnd = NULL; 
ShExecInfo.lpVerb = _T("open"); 
ShExecInfo.lpFile = _T("c4.5.exe"); 
ShExecInfo.lpParameters = _T("-f train"); 
ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_HIDE; 
ShExecInfo.hInstApp = NULL; 
ShellExecuteEx(&ShExecInfo); 
WaitCursorBegin(); 
WaitForSingleObject(ShExecInfo.hProcess,INFINITE); 
WaitCursorEnd(); 
比如c:\notpad.exe 可以这么写(比如按钮按下) winexec('c:\notpad.exe',1); 这样就行了
(3)ShellExecute()也行
(4)winexec('C:\WINNT\system32\notepad.exe',0)  参数1:.exe文件全路径名 参数2: 控制参数 

5.关于在VC中调用其它EXE

      三个SDK函数: WinExec,ShellExecute ,CreateProcess可以实现调用其他程序的要求,其中以WinExec最为简单,     ShellExecute比WinExec灵活一些,CreateProcess最为复杂。 WinExec 两个参数,前一个指定路径,后一个指定显示方式。 ShellExecute 可以指定工作目录,并且还可以寻找文件的关联直接打开不用加载与文件关联的应用程序,ShellExecute还可以打开网页,启动相应的邮件关联发送邮件等等。 CreateProcess 一共有十个参数,不过大部分都可以用NULL代替,它可以指定进程的安全属性,继承信息,类的优先级等等。如果我们要得到足够多的关于新的进程的信息,控制新的进程的细节属性,若要达到这些目的,我们就需要使用CreateProcess函数了。 

 三个SDK函数( WinExec、ShellExec、CrateProcess )的语法: 

  • WinExec 这个函数最简单,只有两个参数,原型如下: 
UINT WinExec( LPCSTR lpCmdLine, // 命令路径 
UINT uCmdShow // 显示方式 ; 
使用方法如下: 
WinExec("Notepad.exe", SW_SHOW); // 打开记事本 
WinExec("D:\\Program Files\\Test\\Test.exe",SW_SHOWMAXIMIZED); // 以最大化的方式打开Test.exe 
需要注意的是若用 SW_SHOWMAXMIZED 方式去加载一个无最大化按钮的程序,譬如Neterm,Calc 等等,就不会出现正常的窗体,但是已经被加到任务列表里了。 

  • ShellExecute 原型如下: 
HINSTANCE ShellExecute( HWND hwnd, //父窗口句柄 
LPCTSTR lpOperation, //操作, 打开方式 
"edit","explore","open","find","print","NULL" LPCTSTR lpFile, //文件名,前面可加路径 
LPCTSTR lpParameters, //参数 
LPCTSTR lpDirectory, //默认文件夹 
INT nShowCmd //显示方式 ); 使用方法如下: 
ShellExecute(NULL,"open","C:\\Test.txt",NULL,NULL,SW_SHOWNORMAL); // 打开C:\Test.txt 文件 
ShellExecute(NULL, "open", "iexplore.exe","http://www.welcomebbs.com",/ NULL, NULL, SW_SHOWNORMAL); // 打开网页www.welcomebbs.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不支持定向输出。 

  •  CreateProcess (welcomebbs)原型如下: 

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 //用于在进程创建后接受相关信息 
)

使用方法如下: 
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:\\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,π);

      可以看出,通过上面的几个不同的方法,都可以实现在应用程序中打开其他应用程序的目的,其中有些方法可能会麻烦一点,所以就需要我们根据不同的目的去选择最适合自己的方法去实现自己的目的! 

关于三个SDK函数: WinExec, ShellExecute,CreateProcess(welcomebbs)的注意 

  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:\\Program Files\\Test\\Test.exe",SW_SHOWMAXIMIZED); ShellExecute(NULL,"open","C:\\Test.txt",NULL,NULL,SW_SHOWNORMAL);bool fRet=CreateProcess("D:\\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL

这是一门linux下c++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++在linux下从事网络通讯领域/网络服务器的开发和架构工作。 这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。 本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能: (1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux; (2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪; 在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点: (1)项目本身是一个极完整的多线程高并发的服务器程序; (2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题; (3)根据收到的包的不同来执行不同的业务处理逻辑; (4)把业务处理产生的结果数据包正确返回给客户端; 本项目用到的主要开发技术和特色包括: (1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】; (2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果; (3)线程之间的同步技术包括互斥量,信号量等等; (4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素; (5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程; (6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页