Sunday, September 23, 2012

【C++转载好料】Visual C++启动另一个可执行程序的方案


此文章不是我写的,是转载的,为了让大家能更好地了解,我做了点改正+讲解,并已经测试,在VS2005下是没问题的,原文在:http://blog.csdn.net/weaver2007/article/details/5700312

请记得include一个头文件:windows.h

有三个API函数可以运行可执行文件:
  • WinExec(超简单易用)
  • ShellExecute(较多选项,可以获得运行的程序的hWnd(句柄))
  • CreateProcess(因为使用复杂,比较少用)
【WinExec和ShellExecute比一比】

WinExec
- 短名运行:在%path%变量里面的程序
- 返回的是 启动是否成功值(uint)
- 无法设置运行目录
- 只能打开exe/com等可执行的程序,如果是txt文件,是不会打开的
- 如果你的程序是 命令行界面的,要执行的程序也是 命令行界面的话,运行的程序会在同一个窗体

ShellExecute
- 短名运行:在%path%变量里面的程序 + 某些特别程序(比如winword.exe)
- 返回的是 被执行的程序 的实例句柄(hWnd)
- 可以设置运行目录(Working Directory)
- 对于有关联的文件/协议,比如a.txt和http://www.google.com/,是可以打开的
- 运行的程序会在新的窗体,不管是不是命令行界面

【WinExec篇】

UINT WINAPI WinExec(
  _In_  LPCSTR lpCmdLine,
  _In_  UINT uCmdShow
);
  • lpCmdLine:要执行的程序
  • uCmdShow:指明运行程序的窗体要怎样的,请参考 窗体显示方式常量
返回的东西:运行是否成功值
例子:WinExec(’Notepad.exe Readme.txt’, SW_SHOW)

【ShellExecute篇】
HINSTANCE ShellExecute(
  _In_opt_  HWND hwnd,
  _In_opt_  LPCTSTR lpOperation,
  _In_      LPCTSTR lpFile,
  _In_opt_  LPCTSTR lpParameters,
  _In_opt_  LPCTSTR lpDirectory,
  _In_      INT nShowCmd
);
● hWnd:指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句柄,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。
  ● Operation:指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参数设为NULL时,表示执行默认操作“open”。
  ● FileName:指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。
  ● Parameters:指定命令行参数,可设置为NULL。
  ● Directory:指定运行目录,可设置为NULL。
  ● ShowCmd:指定 窗体显示方式,请参考 窗体显示常量
  若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。  

【窗体显示方式常量】
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同

【CreateProcess篇】
注意:这货功能非常多,但会令人吐血(对于我这样的新手来说),如非必要强烈建议避免用这个


BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);
  • lpApplicationName 和 lpCommandLine :这个有点乱,与其说多多,不如直接这样看待:<lpApplicationName> <lpCommandLine>
比如一个运行命令:C:\Windows\System32\notepad.exe hello.txt,你可以这样:
lpApplicationName = "C:\Windows\System32\notepad.exe"
lpCommandLine = "hello.txt"
或者这样:
lpApplicationName = NULL
lpCommandLine = "C:\Windows\System32\notepad.exe hello.txt"
但是你不能这样:
lpApplicationName = "C:\Windows\System32\notepad.exe hello.txt"
lpCommandLine = NULL
如果不要参数,你就可以这样玩:
lpApplicationName = "C:\Windows\System32\notepad.exe"
lpCommandLine = NULL
或者:
lpApplicationName = NULL
lpCommandLine = "C:\Windows\System32\notepad.exe"
  • lpProcessAttributes 和  lpThreadAttributes:真心不清楚什么来的,请设置为NULL
  • bInheritHandles:决定子进程对父进程继承性,一般设为FALSE。
  • dwCreationFlags:用于标识标志,以便用于规定如何来创建新进程。点击查看相关常量
  • lpEnvironment:指向包含新进程将要使用的环境字符串的内存块,可以设置为NULL
  • lpCurrentDirectory:指定运行目录,可以设置为NULL
  • lpStartupInfo:这货很乱,我消化不来,所以请看后面的example吧……
凌晨1点了,我先睡觉了,有空再续……

1 comment:

  1. lpStartupInfo 其实可以直接GetStartupInfo 获取 STARTUPINFO 结构的,大多数不必更改~

    我帮你略略解释了下

    typedef struct _STARTUPINFO {
    DWORD cb; //本结构的字节大小
    LPTSTR lpReserved; //微软最爱的东西:保留的字串
    LPTSTR lpDesktop; //这我不知道。。
    LPTSTR lpTitle; //给console程序用的,指定它的title
    DWORD dwX; //X坐标
    DWORD dwY; //Y坐标,忘记要指定那个参数才会使用这些数据。。
    DWORD dwXSize;
    DWORD dwYSize;
    DWORD dwXCountChars; //Console,指定行数
    DWORD dwYCountChars;
    DWORD dwFillAttribute; //Console,指定字体、背景颜色
    DWORD dwFlags; //标志。。
    WORD wShowWindow; //是否要显示窗口啊?
    WORD cbReserved2; //又是保留的
    LPBYTE lpReserved2; //这个也是保留
    HANDLE hStdInput; //标准句柄,可以重定向到
    HANDLE hStdOutput; //我用个这个实现了获取CMD的输出
    HANDLE hStdError; //
    } STARTUPINFO, *LPSTARTUPINFO;


    http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx

    ReplyDelete

你对此有何看法?