VC 调用外部可执行程序

方法一:
WinExec( "notepad.exe,SW_SHOW ");
方法二:
ShellExecute(NULL, "open ", "notepad.exe ",NULL,NULL,SW_SHOWMAXIMIZED)
方法三:
STARTUPINFO   si;
::ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
PROCESS_INFORMATION   pi;

if(::CreateProcess(NULL,_T( "notepad.exe "),NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi))
{
        ::CloseHandle(pi.hThread);
        ::WaitForSingleObject(pi.hProcess);

}


CreateProcess、CreateProcessAsUser、CreateProcessWithLogonW  
安全性评价
第一个参数   lpApplicationName   可以为   NULL。在这种情况下,可执行程序的名称必须是   lpCommandLine   中第一个用空格分隔的字符串。但是,如果可执行程序的名称或路径名中有空格,则存在一定的风险,因为如果空格处理不当,就可能会运行恶意的可执行程序。以下示例是危险的,因为该进程将试图运行“Program.exe”(如果该程序存在),而不是“foo.exe”。

CreateProcess(NULL,   "C:\Program   Files\foo ",   ...)  

如果恶意用户要在系统中创建名为“Program.exe”的特洛伊程序,那么任何使用“Program   Files”目录不正确地调用   CreateProcess   的程序都将启动特洛伊程序,而不是要调用的应用程序。

注意不要为   lpApplicationName   传递   NULL,以避免函数根据其运行时参数来分析并确定可执行文件路径名。否则,如果   lpApplicationName   为   NULL,则用引号将   lpCommandLine   中的可执行路径引起,如下例所示。

CreateProcess(NULL,   "\ "C:\Program   Files\foo.exe\ "   -L   -S ",   ...)  

WinExec
安全性评价
可执行名称被视为   lpCmdLine   中的第一个用空格分隔的字符串。   但是,如果可执行程序的名称或路径名中有空格,则存在一定的风险,因为如果空格处理不当,就可能会运行恶意的可执行程序。以下示例是危险的,因为该进程将试图运行“Program.exe”(如果该程序存在),而不是“foo.exe”。

WinExec( "C:\Program   Files\foo ",   ...)  
如果恶意用户要在系统中创建名为“Program.exe”的特洛伊程序,那么任何使用“Program   Files”目录不正确地调用   WinExec   的程序都将启动特洛伊程序,而不是要调用的应用程序。

就安全性而言,我们强烈建议您使用   CreateProcess   而不是   WinExec。但是,如果您由于遗留问题而必须使用   WinExec,则务必要将应用程序名用引号引起来,如下例所示:

WinExec( "\ "C:\Program   Files\foo.exe\ "   -L   -S ",   ...)   


system
WinExec
ShellExecute
CreateProcess


注意:WinExec() 第一个参数路径反斜杠应为双反斜杠

返回值:

 
  若函数调用成功,则返回值大于31。若函数调用失败,则返回值为下列之一:
  ① 0:系统内存或资源已耗尽。
     ② ERROR_BAD_FORMAT:EXE文件无效(非Win32.EXE或.EXE影像错误)。
  ③ ERROR_FILE_NOT_FOUND:指定的文件未找到。
  ④ ERROR_PATH_NOT_FOUND:指定的路径未找到。
 
  大于 31 {调用成功}
  等于 0 {内存不足}
  ERROR_FILE_NOT_FOUND = 2; {文件名错误}
  ERROR_PATH_NOT_FOUND = 3; {路径名错误}
  ERROR_BAD_FORMAT = 11; {EXE 文件无效}
 
  //uCmdShow 参数可选值:
  SW_HIDE = 0; {隐藏, 并且任务栏也没有最小化图标}
  SW_SHOWNORMAL = 1; {用最近的大小和位置显示, 激活}
  SW_NORMAL = 1; {同 SW_SHOWNORMAL}
  SW_SHOWMINIMIZED = 2; {最小化, 激活}
  SW_SHOWMAXIMIZED = 3; {最大化, 激活}
  SW_MAXIMIZE = 3; {同 SW_SHOWMAXIMIZED}
  SW_SHOWNOACTIVATE = 4; {用最近的大小和位置显示, 不激活}
  SW_SHOW = 5; {同 SW_SHOWNORMAL}
  SW_MINIMIZE = 6; {最小化, 不激活}
  SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}
  SW_SHOWNA = 8; {同 SW_SHOWNOACTIVATE}
  SW_RESTORE = 9; {同 SW_SHOWNORMAL}
  SW_SHOWDEFAULT = 10; {同 SW_SHOWNORMAL}
  SW_MAX = 10; {同 SW_SHOWNORMAL}


WinExec, ShellExecute,CreateProcess 区别

其中以 WinExec最为简单, ShellExecuteWinExec灵活一些, CreateProcess最为复杂。

    WinExec两个参数,前一个指定路径,后一个指定显示方式。

    ShellExecute 可以指定工作目录,并且还可以寻找文件的关联直接打开不用加载与文件关联的应用程序,ShellExecute还可以打开网页,启动相应的邮件关联发送邮件等等。

    CreateProcess 一共有十个参数,不过大部分都可以用NULL代替,它可以指定进程的安全属性,继承信息,类的优先级等等。如果我们要得到足够多的关于新的进程的信息,控制新的进程的细节属性,若要达到这些目的,就需要使用CreateProcess函数了。具体用法如下:

WinExec

这个函数最简单,只有两个参数,原型如下:
UINT WinExec(
    LPCSTR lpCmdLine,    // 命令路径
    UINT uCmdShow       // 显示方式,共有11种,具体可以查阅MSDN的ShowWindow函数
);

使用方法如下:
WinExec("Notepad.exe", SW_SHOW); // 打开记事本
WinExec("D:\\Program Files\\Test\\Test.exe",SW_SHOWMAXIMIZED); // 以最大化的方式打开Test.exe(注意文件名的大小写也必须完全一样)
需要注意的是若用 SW_SHOWMAXMIZED 方式去加载一个无最大化按钮的程序,譬如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", "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不支持定向输出。

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);

由此,我就设计了三个按钮,分别用这三种函数调用了三个应用程序,设置在每个按钮的ONCLICK消息中:

    WinExec("taskmgr",SW_NORMAL); //调用系统任务管理器
    ShellExecute(NULL,"open","C:\ReadMe.txt","","",SW_SHOW); //打开C盘下的ReadMe文件
    STARTUPINFO si={sizeof(si)};
    PROCESS_INFORMATION pi;
    CreateProcess(NULL,"cleanmgr",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); //调用系统的清理磁盘程序  


你可能感兴趣的:(Security,null,Class,exe,任务,attributes)