MFC 打开外部EXE文件的三种方法

时间:2020-12-23 21:19:01
2010年07月30日 
  目前知道三种方式:WinExec,ShellExecute ,CreateProcess,别人已经总结的很好了《vc中调用其他应用程序的方法(函数) winexec,shellexecute ,createprocess》,我全文转载一下,另外后面加点自己的总结(黑体部分,除了标题)。 
  三个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 等等,就不会出现正常的 窗体,但是已经被加到任务列表里了。 
  这个函数只能打开exe文件。  
  需要的头文件:windows.h,winbase.h(前者是试验出来,后者是msdn上说明),另外,这两者的先后顺序不能变。 
  msdn上的说明:[url]http://msdn.microsoft.com/en-us/library/ms687 393[/url](VS.85).aspx  
  (二)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", " 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不支持定向输出。 
  这个函数可以打开任意文件,会调用系统注册的程序来打开对应后缀名的文件。 
  需要的头文件:windows.h,shellapi.h(前者是我试验出来的,后者是msdn说需要的)。另外这两者的先后顺序不能变。 
  msdn上说明:[url]http://msdn.microsoft.com/en-us/library/bb762 153[/url](VS.85).aspx  
  (三)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 //用于在进程创建后接受相关信息  
  );  
  使用方法如下:  
  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,&pi); 
  这个函数可以打开任意文件,会调用系统注册的程序来打开对应后缀名的文件。 
  需要的头文件:windows.h,winbase.h(前者是试验出来,后者是msdn上说明),另外,这两者的先后顺序不能变。 
  msdn上的说明:[url]http://msdn.microsoft.com/en-us/library/ms682 425[/url](VS.85).aspx 
  可以看出,通过上面的几个不同的方法,都可以实现在应用程序中打开其他应用程序的目的,其中有些方法可能会麻烦一点,所以就需要我们根据不同的目的去选择最适合自己的方法去实现自己的目的!  
  关于三个SDK函数: WinExec, ShellExecute,CreateProcess 的其他注意事项:  
  1、定义头文件  
  原作者的内容删去。 
  这个是引用新函数都必须注意的内容。但是MS的头文件引用顺序有点怪,比如上面的三种清理。另外,如果用了预编译,那么记得在任何源程序中的#include "stdafx.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,NULL,&si,&pi) 
  3、注意文件的路径 
  在程序a调用程序b的时候,b原来的默认的当前路径都会变成a的当前路径。所以,一定要注意。 
  可以养成使用绝对路径的习惯,另外,记得打开文件之类的操作,一定要验证是否有错。 
  VC++6.0  
  Win95  
  如何在VC++中调用外部的DOS程序?它的函数是什么?如果用API,它的函数是什么?  
  回答:  
  你可以使用Windows API函数WinExec、ShellExecute。这两个函数可以调用Windows和DOS程序。WinExec主要运行EXE文件。如:  
  WinExec("Notepad.exe Readme.txt", SW_SHOW);  
  ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。如:  
  ShellExecute(0, "open", "http://askpro.yeah.net", NULL, NULL, 0);  
  另外,参考QA000583 "外调一个DOS程序,但是又不想显示其产生的窗口"。  
  Vc 5.0  
  Windows 95  
  我正在编写一个程序,想外调一个现成的Com,但是又不想显示其产生的窗口,我试过可以关闭该窗口,一样能运行,可是在我的程序中如何获取该窗口句柄,如何自动关闭它?(飞飞)   
  其实使用ShellExecute调用DOS程序时可以不显示窗口,如:  
  ShellExecute(0, "open", "c:\\tools\\arj.exe", "a c:\\p.arj c:\\*.bat c:\\*.sys", NULL, SW_HIDE);  
  对于你的问题,你可以使用FindWindow获得句柄,但关掉窗口就不能再继续执行了。而你说的关闭窗口还能执行,大概是因为在你关闭窗口时已经运行结束了。   
  #include "stdafx.h" 
  #include  
  #include //ShellExecute 要引用的库 
  int main(int argc, _TCHAR* argv[]) 
  {     
  ShellExecute(NULL,NULL,_T("E:\\Projekt1.exe"),NULL ,NULL,SW_SHOW); 
  getchar(); 
  return 0; 
  } 
  #include "stdafx.h" 
  #include   
  #include   
  #include  
  DWORD WINAPI ThreadWork(LPVOID num) 
  { 
  printf("%d\n",num); 
  return 0; 
  } 
  int _tmain(int argc, _TCHAR* argv[]) 
  { 
  DWORD dwThreadID[5];  
  HANDLE threadhandle=CreateThread(NULL, 
  0, 
  ThreadWork, 
  (LPVOID)2,//传递的参数 
  0, 
  &dwThreadID[0]); 
  getchar();  
  return 0; 
  } 
  本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jiangxinyu/archive/2010/03/18 /5393037.aspx