[转]WinExec、ShellExecute和CreateProcess及返回值判断方式  

http://www.cnblogs.com/ziwuge/archive/2012/03/12/2392472.html

有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。CreateProcess因为使用复杂,比较少用。

  WinExec主要运行EXE文件。
  ⑴ 函数原型: UINT Win Exec(LPCSTR lpCmdLine, UINT uCmdShow); 
  ⑵ 参数: 
  lpCmdLine:指向一个空结束的字符串,串中包含将要执行的应用程序的命令行(文件名加上可选参数)。 
  uCmdShow:定义Windows应用程序的窗口如何显示,并为CreateProcess函数提供STARTUPINFO参数的wShowWindow成员的值。 
  ⑶ 返回值: 
  若函数调用成功,则返回值大于31。若函数调用失败,则返回值为下列之一: 
  ① 0:系统内存或资源已耗尽。 
  ② ERROR_BAD_FORMAT:EXE文件无效(非Win32.EXE或.EXE影像错误)。 
  ③ ERROR_FILE_NOT_FOUND:指定的文件未找到。 
  ④ ERROR_PATH_NOT_FOUND:指定的路径未找到。 
 
 虽然Microsoft认为WinExec已过时,但是在许多时候,简单的WinExec函数仍是运行新程序的最好方式。简单地传送作为第一个参数的
命令行,还需要决定如何显示程序(该程序也许会忽视它)的第二个参数。通常,将其设置为SW_SHOW,也可尝试SW_MINIMIZED或
SW_MAXIMIZED。WinExec不允许用CreateProcess获得的所有选项,而它的确简单。

  ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。 

1、标准用法
  ShellExecute函数原型及参数含义如下:

HINSTANCE ShellExecute(HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters,  LPCTSTR lpDirectory, INT nShowCmd);

  ●hWnd:用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句 柄,即Application.Handle,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。  
  
●lpOperation:用于指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的
文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参
数设为nil时,表示执行默认操作“open”。  
  ●lpFileName:用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。  
  ●lpParameters:若FileName参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为nil或PChar(0)。  
  ●lpDirectory:用于指定默认目录。  
  ●lpShowCmd:若FileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。

  返回值:

#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <shellapi.h>

int main( void ){    HINSTANCE hNewExe = ShellExecuteA(NULL, "open", "d:\\tese.log", NULL, NULL, SW_SHOW);    if ((DWORD)hNewExe <= 32)    {        printf("return value:%d\n", (DWORD)hNewExe);    }    else    {        printf("successed!\n");    }   printf("GetLastError: %d\n", GetLastError());    system("pause");    return 1;}

  当“D:\\test.log”文件不存在是,执行结果如下:
  这里若函数执行错误, GetLastError()不一定能捕获到错误代码,例如当“d:\\tese.log”文件存在,将记事本"notepad.exe"命名为其他名字时:

  另外两个函数的返回值就不列出了。

2、特殊用法

  1)如果将FileName参数设置为“http:”协议格式,那么该函数将打开默认浏览器并链接到指定的URL地址。若用户机器中安装了多个
浏览器,则该函数将根据Windows 9x/NT注册表中http协议处理程序(Protocols Handler)的设置确定启动哪个浏览器。  
  格式一:http://网站域名。        如:ShellExecute(handle, “open”, “http://www.neu.edu.cn”, nil, nil, SW_SHOWNORMAL);  
  格式二:http://网站域名/网页文件名。  如:ShellExecute(handle, “open”, “http://www.neu.edu.cn/default.htm”, nil, nil, SW_SHOWNORMAL);  
 
 2)如果将FileName参数设置为“mailto:”协议格式,那么该函数将启动默认邮件客户程序,如Microsoft
Outlook(也包括Microsoft Outlook Express)或Netscape
Messanger。若用户机器中安装了多个邮件客户程序,则该函数将根据Windows
9x/NT注册表中mailto协议处理程序的设置确定启动哪个邮件客户程序。  
  格式一:mailto:     如:ShellExecute(handle, "open", "mailto:", nil, nil, SW_SHOWNORMAL);打开新邮件窗口。  
  格式二:mailto:用户账号@邮件服务器地址  如:ShellExecute(handle, "open", "mailto:who@mail.neu.edu.cn", nil, nil, SW_SHOWNORMAL);
  打开新邮件窗口,并自动填入收件人地址。若指定多个收件人地址,则收件人地址之间必须用分号或逗号分隔开(下同)
如:ShellExecute(this->m_hWnd, "open", "mailto:nishinapp@yahoo.com", "", "", SW_SHOW);
  格式三:mailto:用户账号@邮件服务器地址?subject=邮件主题&body=邮件正文  
  如:ShellExecute(handle, "open", "mailto:who@mail.neu.edu.cn?subject=Hello&Body=This is a test", nil, nil, SW_SHOWNORMAL);
  打开新邮件窗口,并自动填入收件人地址、邮件主题和邮件正文。若邮件正文包括多行文本,则必须在每行文本之间加入换行转义字符%0a。

例子(delphi):  
在一个应用程序调用c:Project1.exe;  
  ShellExecute(handle, ’open’,’c:Project1.exe’,’字串内容’,nil, SW_SHOWNORMAL);  
在Project1.exe里可以调用:

procedure TForm1.FormCreate(Sender: TObject);  var i:integer;  begin  for i:=1 to paramcount do  if ParamStr(i)〈〉’’ then showmessage(ParamStr(i));  end; 

最后的那个参数,为窗口指定可视性方面的一个命令。 请用下述任何一个常数  
SW_HIDE 隐藏窗口,活动状态给令一个窗口  
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口  
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态  
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态  
SW_SHOWMAXIMIZED 最大化窗口,并将其激活  
SW_SHOWMINIMIZED 最小化窗口,并将其激活  
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口  
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口  
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口  
SW_SHOWNORMAL 与SW_RESTORE相同

  3、深入浅出ShellExecute  译者:徐景周(原作:Nishant       S)
      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);   

使用CreateProcess命令 
  ⑴ 函数原型:

BOOL CreateProcess(  LPCTSTR lpApplicationName,  LPTSTR lpCommandLine,  LPSECURITY_ATTRIBUTES lpProcessAttributes,   LPSECURITY_ATTRIBUTES lpThreadAttributes,   BOOL bInheritHandles,   DWORD dwCreationFlags,  LPVOID lpEnvironment,   LPCTSTR lpCurrentDirectory,   LPSTARTUPINFO lpStartupInfo,   LPPROCESS_INFORMATION lpProcessInformation  );  

  ⑵ 参数: 
  lpApplicationName:指向一个以空结尾的串,他指定了要执行的模块 
  lpCommandLine:指向一个以空结尾的串,该串定义了要执行的命令行。 
  lpProcessAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。 
  lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。  
  bInheritHandles,:表明新进程是否从调用进程继承句柄。 
  dwCreationFlags:定义控制优先类和进程创建的附加标志。 
  lpEnvironment:指向一个新进程的环境块。 
  lpCurrentDirectory:指向一个以空结尾的串,该串定义了子进程的当前驱动器和当前目录。 
  lpStartupInfo:指向一个STARTUPINFO结构,该结构定义了新进程的主窗口将如何显示。 
  lpProcessInformation:指向PROCESS_INFORMATION结构,该结构接受关于新进程的表示信息。 
  ⑶ 返回值: 
  若函数调用成功,则返回值不为0;若函数调用失败,返回值为0。

  在上述参数中,参数lpStartupInfo是STARTUPINFO结构。可以用来设置控台的标题,新窗口的的初始大小和位置,及重定向标
准输入
和输出。新程序通常可以忽略多数这些数据项,如果选择那样做的话。可以规定该结构体中的标志,已表明要设置的数据段。有时,不想设置任何信息,也必须传递

一个有效的指针给空结构(确定设置大小到cb,及设置dwFlags成员为0)。参数lpProcessInformation返回进程和线程句柄,还包
括进程和线程ID。这些句柄拥有在参数lpProcessAttributes和lpThreadAttributes中规定的访问。 
  要
注意,针对CreateProcess的一些参数对控制台应用程序是特定的,而其它参数则对各种应用程序有用。大多数情况下,并不一定要填入
STARTUPINFO结构,但无论如何必须提供它。其返回值是布尔型的,而真正感兴趣的返回值发生于作为参数传送的结构中
(PROCESS_INFORMATION)。CreateProcess返回该结构中的进程ID及其句柄,以及初始线程ID及其句柄。可以将ID发送到
其它进程,或使用句柄来控制新进程。

  ShellExecute和WinExec命令用于简单的作业。如果要完全控制一个新进程,就必须调用CreateProcess。 
【参考资料 感谢作者】
1、WinExec、ShellExecute和CreateProcess 
2、WINEXEC, SHELLEXECUTE, CREATEPROCESS

[转]WinExec、ShellExecute和CreateProcess及返回值判断方式的更多相关文章

  1. Java多线程和并发(四),线程返回值获取方式和Callable接口

    目录 1.主线程等待法 2.使用Thread类的join()阻塞当前线程,等待子线程执行完毕 3.通过Callable接口实现:通过FutureTask Or线程池获取 四.线程返回值获取方式和Cal ...

  2. system系统调用返回值判断命令是否执行成功

    system函数对返回值的处理,涉及3个阶段: 阶段1:创建子进程等准备工作.如果失败,返回-1. 阶段2:调用/bin/sh拉起shell脚本,如果拉起失败或者shell未正常执行结束(参见备注1) ...

  3. python os.system()返回值判断

    最近遇到os.system()执行系统命令的情况,上网搜集了一下资料,整理如下,以备不时之需,同时也希望能帮到某些人. 一.python中的 os.system(cmd)的返回值与linux命令返回值 ...

  4. Ext_两种处理服务器端返回值的方式

    1.Form表单提交返回值处理 //提交基本信息表单  f.form.submit({      clientValidation:true,      //表单提交后台处理地址      url:' ...

  5. Python re 模块findall() 函数返回值展现方式详解

    findall 函数: 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表. 注意: match 和 search 是匹配一次 findall 匹配所有,mat ...

  6. 通过识别页面内容获得返回值判断后续执行(exists指令的用法)

    本案例主要用到airtest 的exists指令 从指令解释可以知道,当判断某图片不存在的时候,会返回false值 脚本思路即为如果返回值==false则执行A,!=fales则执行B 下图脚本思路, ...

  7. springMVC中响应的返回值获取方式

    package com.hope.controller;import com.hope.domain.User;import org.springframework.stereotype.Contro ...

  8. a标签根据js返回值判断页面是否跳转

    a标签再跳转之前先判断是否符合条件,符合可以跳转,不符合不可以跳转. 自己遇到的问题是:在js方法中根据条件就return结果,但是不行. 原因是:在js方法中return后不会结束整个js方法(ac ...

  9. ***CI新增记录成功后的返回值判断,是用isset还是empty

    Q: 新增记录插入成功后,加了一个return $this->db->insert_id(); $digg_id = $this->m_feed_digg->create(js ...

随机推荐

  1. pb中打开窗口并传递参数

    try long ll_result; ll_result=1;openwithparm(w_sb_order,UserCode);catch(RuntimeError er)  errorMsg=e ...

  2. 再论prototype

    前段时间曾经写过一篇关于prototype原型的文章(http://www.cnblogs.com/ttcc/p/3751604.html),但是对于JS的核心之一,还是应该多多熟悉才行,常回过头来看 ...

  3. VS2010插件及快捷键设置

    几个常用的Visual Studio插件,番茄助手以及如下的插件,具体作用可用通过Google自行获取. 安装番茄助手后,可用在源文件和头文件中快速切换.但为了更方便使用,建议设置快捷键. vs201 ...

  4. poj2031 Building a Space Station

    这题目,用G++ WA,用C++ AC. 题目要求,现给出n个球,然后要使每两个球直接或者间接连通,可以在任意两球之间做管道(在表面),最后的要求是,如果使得都连通的话,管道最小长度是多少. 思路简单 ...

  5. javascript之toString()和valueOf()函数

    1.我们为什么要了解这两种方法 众所周知,toString()函数和valueOf函数,这两个函数是Object类的对象生来就拥有的,而且他们还可以允许我们重写,那么,这两个函数到底有什么用呢? 从名 ...

  6. C# 类型转换 Dictionary转Model类

    /// <summary> /// 把Model转换为DataRow /// </summary> /// <typeparam name="T"&g ...

  7. 配置DNS域名解析服务器

    bind这个DNS域名解析服务器解析好后,执行下面的语句实现开启服务 named -c named.conf & -c指配置脚本named.conf的文件地址 named.conf主要有下面几 ...

  8. Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed.

    地图定位 错误:使用CoreLocation获取地理位置信息,报错 Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be ...

  9. [转]10分钟入门python

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为Rocrocket Wu. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体 ...

  10. Linux Hugetlbfs内核源码简析-----(二)Hugetlbfs挂载

    本文只讨论执行"mount none /mnt/huge -t hugetlbfs"命令后,mount系统调用的执行过程(基于Linux-3.4.51),不涉及进程相关的细节. m ...