windows下想要创建一个子进程不如linux的fork函数来得方便,通过CreateProcess函数创建一个新的进程,函数的定义如下

[cpp]  view plain copy
  1. BOOL CreateProcess(
  2.  LPCTSTR lpApplicationName, // 应用程序名称
  3.  LPTSTR lpCommandLine, // 命令行字符串
  4.  LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程的安全属性
  5.  LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性
  6.  BOOL bInheritHandles, // 是否继承父进程的属性
  7.  DWORD dwCreationFlags, // 创建标志
  8.  LPVOID lpEnvironment, // 指向新的环境块的指针
  9.  LPCTSTR lpCurrentDirectory, // 指向当前目录名的指针
  10.  LPSTARTUPINFO lpStartupInfo, // 传递给新进程的信息
  11.  LPPROCESS_INFORMATION lpProcessInformation // 新进程返回的信息
  12. );

下面写一个创建进程和简单的控制示例,首先创建一个小程序,作为子进程的实体

[cpp]  view plain copy
  1. #include<iostream>
  2. #include<Windows.h>
  3. using namespace std;
  4. int main(int argc, char *argv[])
  5. {
  6. cout << "args_num: " << argc << endl;
  7. for(int i = 0;i < argc;i ++){
  8. cout << "arg " << i << " = " << argv[i] << endl;
  9. }
  10. return 0;
  11. }

主要是打印进程的传入参数列表,下面是创建子进程的代码,运行后可以看到,子进程也能获取到传入参数了。

[cpp]  view plain copy
  1. #include<iostream>
  2. #include<Windows.h>
  3. using namespace std;
  4. int main()
  5. {
  6. char cWindowsDirectory[MAX_PATH];
  7. //LPTSTR 与 wchar_t* 等价(Unicode环境下)
  8. LPTSTR cWinDir = new TCHAR[MAX_PATH];
  9. GetCurrentDirectory(MAX_PATH, cWinDir);
  10. LPTSTR sConLin = wcscat(cWinDir , L"\\..\\Debug\\another.exe a b c d");
  11. STARTUPINFO si;
  12. PROCESS_INFORMATION pi;
  13. ZeroMemory(&si, sizeof(si));
  14. ZeroMemory(&pi, sizeof(pi));
  15. //创建一个新进程
  16. if(CreateProcess(
  17. NULL,   //  指向一个NULL结尾的、用来指定可执行模块的宽字节字符串
  18. sConLin, // 命令行字符串
  19. NULL, //    指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。
  20. NULL, //    如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。<同上>
  21. false,//    指示新进程是否从调用进程处继承了句柄。
  22. 0,  //  指定附加的、用来控制优先类和进程的创建的标
  23. //  CREATE_NEW_CONSOLE  新控制台打开子进程
  24. //  CREATE_SUSPENDED    子进程创建后挂起,直到调用ResumeThread函数
  25. NULL, //    指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境
  26. NULL, //    指定子进程的工作路径
  27. &si, // 决定新进程的主窗体如何显示的STARTUPINFO结构体
  28. &pi  // 接收新进程的识别信息的PROCESS_INFORMATION结构体
  29. ))
  30. {
  31. cout << "create process success" << endl;
  32. //下面两行关闭句柄,解除本进程和新进程的关系,不然有可能不小心调用TerminateProcess函数关掉子进程
  33. //      CloseHandle(pi.hProcess);
  34. //      CloseHandle(pi.hThread);
  35. }
  36. else{
  37. cerr << "failed to create process" << endl;
  38. }
  39. Sleep(100);
  40. //终止子进程
  41. TerminateProcess(pi.hProcess, 300);
  42. //终止本进程,状态码
  43. ExitProcess(1001);
  44. return 0;
  45. }

CreateProcess的参数虽然多而且麻烦,其实大部分设置为NULL即可,右边这个链接里面有多进程编程相关的函数介绍:http://blog.csdn.net/bxhj3014/article/details/2082255

=======================CreateProcess()详解及用法=======================

CreateProcess() 函数原型如下:

[C++]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
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
);

该函数用来创建一个新的进程。

第 1 个参数  lpApplicationName 是输入参数,指向启动进程的 exe 文件。

第 2 个参数  lpCommandLine 是输入参数,是启动进程的命令行中的参数。

当这两个参数都不为 NULL 时,第 1 个参数指定要启动的进程 exe 文件(不带参数),第 2 个参数指定启动进程所需参数。第 1 个参数也可以为 NULL,此时第 2 个参数就不能为 NULL,在 lpCommandLine 需要指定出要启动的程序名以及所接参数,彼此间以空格隔开,其中第 1 个参数即是程序名。

第 3 个参数  lpProcessAttributes 是输入参数,指向 SECURITY_ATTRIBUTES 结构变量,是进程的安全属性,可以为 NULL 则使用默认的安全属性。

第 4 个参数  lpThreadAttributes 是输入参数,同第 3 个参数一样,指向 SECURITY_ATTRIBUTES 结构变量。

第 5个参数  bInheritHandles 是输入参数,表示新进程是否从调用进程处继承了句柄。如果参数的值为 TRUE,调用进程中的每一个可继承的打开句柄都将被子进程继承。被继承的句柄与原进程拥有完全相同的值和访问权限;如果设为 FALSE,那么不继承。

第 6 个参数  dwCreationFlags 是输入参数,表示进程的创建标志以及优先级控制。如 : CREATE_NEW_CONSOLE 会使新建的控制台程序拥有一个新的控制台; DEBUG_PROCESS 调用进程将被当作一个调试程序,并且新进程会被当作被调试的进程。系统把被调试程序发生的所有调试事件通知给调试器。

第 7 个参数  lpEnvironment 是输入参数,指向新进程的环境变量块,如果设置为 NULL,那么使用父进程的环境变量。

第 8 个参数  lpCurrentDirectory 是输入参数,指定创建后新进程的当前目录,如果设置为 NULL,那么就在父进程所在的当前目录。

第 9 个参数  lpStartupInfo 是输入参数,指向一个 STARTUPINFO 结构,该结构里可以设定启动信息,可以设置为 NULL 。

第 10 个参数  lpProcessInformation 是输出参数,指向一个 PROCESS_INFORMATION 结构,返回被创建进程的信息。

测试代码:

[C++]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "stdafx.h"
#include <locale.h>
#include <Windows.h>
int _tmain( int argc, _TCHAR* argv[])
{
    PROCESS_INFORMATION ProInfo;     //进程信息结构
    STARTUPINFO    StartInfo;
    ZeroMemory ( &StartInfo, sizeof (StartInfo));
         LPTSTR   szPrameter = TEXT( "C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe [url]www.groad.net[/url]" );
     TCHAR szCmdLine[2048] = {0};
    CopyMemory(szCmdLine, szPrameter, 2*_tcslen(szPrameter));
        ZeroMemory (&ProInfo, sizeof (ProInfo));
  if (!CreateProcess ( NULL,         // 执行的程序名
            szCmdLine,                     // 命令行指定
            NULL,                         // 进程安全属性,NULL 时使用默认安全属性
            NULL,                         // 线程安全属性,NULL 时使用默认安全属性
            FALSE,                         // 不继承句柄
            0,                             // 进程创建标志
            NULL,                         // 环境变量块,为 NULL 时使用父进程环境变量
            NULL,                     // 新进程目录
            &StartInfo,                         // 启动信息结构
            &ProInfo)                     // 进程信息结构
        ) {
            _tprintf (TEXT( "CreateProcess failed : %d\n" ), GetLastError());
             return (-1);
    }
     // 等待子进程结束
    WaitForSingleObject(ProInfo.hProcess, INFINITE);
                     
    CloseHandle ( ProInfo.hProcess );
    CloseHandle ( ProInfo.hThread );
     return 0;
}

上面程序启动谷歌 Chrome 浏览器并打开  www.groad.net 这个主页。在程序中,当第 1 个参数为 NULL 时,要启动的程序以及网址参数均指定在第 2 个参数中。注意,不能直接将参数 szPrameter 直接填写到第 2 个参数中,因为指定的命令行参数中含有空格,这样往往会造成参数解析错误,比如它会被解析成:

C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe  www.groad.net.exe

也就是会认为  chrome.exe www.groad.net.exe 这就是一个程序,这是无法执行的。

而将命令行参数拷贝到数组中却是可行的,但如此一来却要多定义一个数组。如果是英文 Windows 环境,并无需构建多字符程序,那么可以将引号把路径括起来,这也不会出错,比如:

CreateProcess (NULL, "\"Path to exe\" -p1-p2 -p3", ...);

注意上面的路径使用反斜杠转义了括起路径的双引号。

但是,如果在第 1 个参数和第 2 个参数里分别指定程序名和参数,那么也无需添加一个数组来存储命令行参数,但第 2 个参数中指定的命令行参数注意前面要添加一个空格,否则可能无法正确解析参数,比如:

LPTSTR szPname = TEXT("D:\\Program Files (x86)\\Maxthon3\\Bin\\Maxthon.exe");
    LPTSTR szPrameter = TEXT("www.groad.net");      //网址前无空格,错误。正确的形式是添加一个空格

这里只是针对浏览器打开网址这种情况,并非所有的情形都会没问题,比如我测试时,IE 和 MaxThon 是需要在网址面前添加空格的,否则打开的是一个空白页。但对于 Chrome ,不管网址前加不加空格都只能打开空白页,得用上面添加的数组情况方能正常。这也许和浏览器程序本身有关。如果用的是记事打开一些文本,如果后面的文本路径参数不添加空格,那么打开空白,反之正常;而对于 UE ,那么即使后面不添加空格也照样打开,所以从这两个例子看来,仍然是和程序本身有关。但是,添加一个空格会保持较好的兼容性,如若还不行,可以考虑用一个数组来接纳所有的命令行参数。

另外,程序中使用了 WaitForSingleObject() 函数以等待子进程的退出,如当我们关闭了浏览器,那么上面的程序也随之结束,否则一直在那等待。

转:http://www.groad.net/bbs/thread-6367-1-1.html

windows下创建进程,CreateProcess()详解及用法相关推荐

  1. Windows下创建进程-CreateProcess()

    原文地址:https://blog.csdn.net/yuyan987/article/details/78644922 函数说明: CreateProcess是Windows下用于创建进程的API函 ...

  2. [转]Windows下安全权限设置详解

    一 Windows下安全权限设置详解 [简 介] 随着动网论坛的广泛应用和动网上传漏洞的被发现以及SQL注入式攻击越来越多的被使用,WEBSHELL让防火墙形同虚设,一台即使打了所有微软补丁.只让80 ...

  3. mysql-win安装教程,WINDOWS下安装MYSQL教程详解

    1.下载安装包 2.配置环境变量 2.1 解压所下载的压缩包 2.2 环境变量 win 10 电脑 这么进去 3.生成data文件 在你解压的目录下,eg:F:\Program Files\mysql ...

  4. Windows下创建进程简介

    正在执行的应用程序称为进程,进程不仅仅是指令和数据,它还有状态.状态是保存在处理器寄存器中的一组值,如当前执行指令的地址.保存在内存中的值,以及唯一定义进程在任一时刻任务的所有其他值.进程与应用程序的 ...

  5. Windows下配置sphinx+reStructuredText详解

    最近有朋友想在windows下做个人笔记,没有找到顺手的工具,问我有什么好的工具推荐.正好前两天在网上看到一款做文档的利器sphinx+reStructText,当时在ubuntu下搭了下环境试了试, ...

  6. VLC-3.0.0(Nightly版)在Linux和Windows下的编译步骤详解

    VLC 3.0.0 Compile vlc的编译一直是个大坑,做过音视频开发的不少人想必都踩过,开篇引用官方wiki一句话: Compiling VLC is not an easy task. 本文 ...

  7. linux下top指令参数详解及用法

    一.命令介绍 Linux top命令用于实时显示 process (进程)的动态. 它用于监控正在运行系统负荷的信息,包括系统负载.CPU利用分布情况.内存使用.每个进程的资源占用情况等. 使用权限: ...

  8. WINDOWS下安装MYSQL—图文详解

    mysql安装过程及注意事项: 1.1. 下载: 我下载的是64位系统的zip包: 下载地址:https://dev.mysql.com/downloads/mysql/ 下载zip的包: 下载后解压 ...

  9. Windows下配置NodeJS环境详解

    1.下载nodejs 在https://nodejs.org/en/中下载node,我选的是左侧稳定版本 2.安装nodejs 将下载的node进行安装如下图一步一步的安装 3.安装后检测是否安装no ...

最新文章

  1. 转:C#中的abstract与virtual
  2. mongodb数据库淘汰_红帽彻底不跟MongoDB玩了,只认PostgreSQL
  3. cpu影响matlab仿真速度吗,Proteus仿真速度很慢的分析
  4. php扑克牌排序,PHP实现判断扑克牌5张连续
  5. Linux驱动(11)--生成设备节点
  6. MySQL怎么查询课程信息_mysql 查询没有学全所有课程的同学的信息
  7. java 解决内存泄露_Java内存泄露的理解与解决
  8. tftp协议服务器IP地址,TFTP服务器的搭建
  9. php mysql begin_PHP mysqli_begin_transaction() 函数用法及示例
  10. Maven的依赖与最佳配置(转载自Maven实战 作者许晓斌)
  11. OPPO加入连接标准联盟董事会;BOSE为领克09汽车打造Centerpoint环绕声音响系统 | 全球TMT...
  12. 关于时域、频域和波数域的一些概念
  13. win10PC上安装deepin深度Linux系统简易教程
  14. HTML11 表格和表单
  15. 如何制作透明的树Shader和一个玻璃Shader
  16. C++抽奖(随机数+人名的不停闪烁)
  17. HarmonyOS应用端云一体化开发主要流程
  18. COMSOL中“模式分析”、“边界模式分析”的区别
  19. 视频教程-Access2013数据库入门教程-Office/WPS
  20. 正版推荐 - Hard Disk Sentinel Pro 专业版硬盘检测工具软件

热门文章

  1. Win11--将右键菜单改回Win10(展开菜单)
  2. 数字图像处理(13): 形态学处理——图像开运算与图像闭运算
  3. Windows值得推荐的桌面管理软件
  4. 查看服务器操作系统版本信息,查看服务器操作系统版本信息
  5. SQL Server Management Studio管理数据库
  6. SQLStudio下载
  7. Python3.x爬虫下载网页图片
  8. C# 读取txt文件生成Word文档
  9. 在虚拟机(centos)配置postgresql数据库(1) - 安装篇
  10. String如何截取字符串长度