windows下创建进程,CreateProcess()详解及用法

2023-11-12

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.   
  4. using namespace std;  
  5.   
  6. int main(int argc, char *argv[])  
  7. {  
  8.     cout << "args_num: " << argc << endl;  
  9.     for(int i = 0;i < argc;i ++){  
  10.         cout << "arg " << i << " = " << argv[i] << endl;  
  11.     }  
  12.     return 0;  
  13. }  
主要是打印进程的传入参数列表,下面是创建子进程的代码,运行后可以看到,子进程也能获取到传入参数了。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

windows下创建进程,CreateProcess()详解及用法 的相关文章

  • 爬虫保存cookies时重要的两个参数(ignore_discard和ignore_expires)的作用

    代码如下 由于临时做的实例采用登录云打码平台的cookies import requests from lxml html import etree from fake useragent import UserAgent from htt
  • 在上传文件的同时 传递参数 (ajax上传文件并传值给后台)

    之前用的ajax方法上传文件 结果这边需要对上传文件进行分类和关键字处理 话不多说直接上代码了 前端html以及js部分 fieldset legend 文件信息 legend table class table style width 1
  • BigInteger和BigDecimal的使用

    1 BigInteger类的常用方法 java math BigInteger类表示一个超大的整数 而且支持任意精度整数的四则运算 加减乘除 常用方法 方法 含义 public BigInteger String val 将 BigInte
  • 多任务

    多任务 1 多任务的概念 多任务的最大好处是充分利用CPU资源 提高程序的执行效率 多任务是指在同一时间内执行多个任务 例如 现在电脑安装的操作系统都是多任务操作系统 可以同时运行着多个软件 多任务的执行方式 并发 并行 是多个任务真正意义
  • grep 常用选项与参数整理

    grep大有学问 大有用处啊 平常只用到了它的20 的功能 整理总结一下 1 grep基本用法 grep acinv color auto A n B n C n 搜寻字符串 文件名 2 常用参数 l 查询多文件时只输出包含匹配字符的文件名
  • Linux-进程简介

    内核代码版本 2 6 11 1 1 进程 进程是任何多道程序设计的操作系统中的基本概念 通常把进程定义为程序执行的一个实例 在Linux源代码中 进程通常称为任务 task 或线程 thread Linux系统的线程实现非常特别 他对线程和
  • 菜鸟学习历程【17】进程控制编程

    进程控制编程 进程 进程是一个具有一定独立功能的程序的一次运行活动 同时也是资源分配的最小单元 进程 程序 程序执行的实例 放到磁盘的可执行文件 进程不可在计算机之间迁移 程序通常对应着文件 静态和可以复制 动态 静态 暂时 进程是一个状态
  • Window10文件在另一个程序中打开无法删除

    1 打开任务管理 点详细信息 2 打开性能 gt 3 打开下方的 资源监视器 4 句柄中输入文件名 5 鼠标右键结束进程 就可以删除文件啦
  • Windbg Preview与虚拟机win10系统实现双机调试

    在驱动开发之调试内核模块中实现了用windbg与虚拟机xp系统下的双机调试 接下来说下怎么使用windbg preview与虚拟机win10系统进行双机调试 主要在三个方面进行配置 win10系统配置 虚拟机配置 windbg previe
  • 进程调度的控制—文件锁

    前言 在进程之间 我们不能决定应该先去调度哪一个进程 这时候我们就需要对一个文件加锁 来要求那个先来执行 整体文件锁 int flock int fd int operation fd 文件描述符 operation 定义的宏 也就是选项
  • caffe 查看caffemodel中的参数与数据

    在用caffe训练完一个模型之后 我们想更加直观的查看这个模型该怎么做呢 caffe框架训练出来的caffemodel是一个类似于黑盒的东西 我们无法直接看到它的本质 需要借助caffe所定义的接口来协助我们 详细的文档在caffe官网上都
  • Linux进程编程(PS: exec族函数、system、popen函数)

    目录 1 进程相关概念 程序和进程 查看系统中的进程 ps指令 top指令 进程标识符 使用getpid 获取 父进程 子进程 2 创建进程fork 进程创建发生了什么 C程序的存储空间如何分配 3 创建进程vfork 区别fork 4 进
  • 关闭WIN10的wsappx进程服务

    关闭原因 打开电脑登录系统后 发现wsappx进程服务占用CPU极高 并且一直没有降低 如下图所示 解决办法 将以下注册表的值由3修改为4重启系统即可 计算机 HKEY LOCAL MACHINE SYSTEM CurrentControl
  • kill掉僵尸进程的方法(kill -9 <PPID>)

    ps A ostat ppid pid cmd grep e Zz 先用以上bash命令找到僵尸进程 Z右边第一列为PPID 第二列为PID kill 9 PPID 即PID对应的父进程即可 kill 9
  • CreateProcess 在 Windows 7 下不会创建额外的控制台窗口?

    我正在尝试使用 CreateProcess 运行一个进程 并在单独的控制台窗口中独立运行它 我可以使用 system 函数来实现这一点 但我更喜欢 CreateProcess 因为它使我可以指定环境和工作目录 获取进程的句柄 以及在需要时通
  • 创建独立进程!

    我正在尝试从 C 中的服务创建一个进程 这个新进程是作为子进程创建的 我想创建一个独立的进程而不是子进程 我正在使用 CreateProcess 函数来实现相同的目的 由于我创建的新进程是一个子进程 当我尝试在服务级别杀死进程树时 它也会杀
  • C++ 从 CreateProcess() 获取 UTF-8 输出

    我无法让它工作 所以我得到 UTF 8 输出CreateProcess into wstring 目前我正在运行此方法来执行此操作 但没有 UTF 8 输出 HANDLE g hChildStd OUT Rd NULL HANDLE g h
  • 从 PowerShell 调用 CreateProcess

    我正在尝试打电话创建进程 http msdn microsoft com en us library windows desktop ms682425 28v vs 85 29 aspx来自 PowerShell API 调用表明它已成功
  • 为什么 CreateProcess 在 Windows Server 2003 64 位中失败?

    我们有一个 32 位应用程序 它在其进程中启动其他 32 位应用程序 该应用程序在其他 64 位平台上运行良好 但在 Windows Server 2003 64 位平台上 我们在尝试启动应用程序时遇到错误 error 193 not a
  • 在调试器下运行时,AssignProcessToJobObject 失败并出现“访问被拒绝”错误

    You do AssignProcessToJobObject并且仅当您在调试器中运行时才会因 访问被拒绝 而失败 为什么是这样 这个问题让我困惑了大约30分钟 首先 您可能需要在您的应用程序中嵌入一个 UAC 清单 正如这里所建议的 ht

随机推荐

  • CSSS样式穿透

    在使用 CSS 样式时 有时候我们希望修改子组件中的样式 但是由于 CSS 的层叠规则 子组件的样式可能会被父组件的样式所覆盖 这时可以使用 CSS 样式穿透 CSS style piercing 来解决这个问题 CSDN上面大多数都是使用
  • 体积

    题目描述 问题描述 给出 n 件物品 每件物品有一个体积 V i 求从中取出若干件物品能够组成的不同的体积和有多少种可能 输入格式 第 1 行 1 个正整数 表示 n 第 2 行 n 个正整数 表示 V i 每两个数之间用一个空格隔开 输出
  • 8-窗口、窗口控件、对话框以及相关功能类-对话框QDialog

    对话框QDialog 对话框 QDialog 是顶层窗口 主要用于短期任务和与用户的简短通信 所谓的顶层窗口 就是可以显示在所有窗口的最前面 也有另一种说法 是指没有父类的窗口 例如 有些警告窗口始终显示在屏幕顶端 直到被用户关闭 QDia
  • java中yield(),sleep()以及wait()的区别

    往往混淆了这三个函数的使用 从操作系统的角度讲 os会维护一个ready queue 就绪的线程队列 队列 是先进先出的 FIFO 并且在某一时刻cpu只为ready queue中位于队列头部的线程服务 但是当前正在被服务的线程可能觉得cp
  • 微信 history.back 时候的 缓存问题处理, 最近搞得我很头疼

    最近在写微信的项目 遇到一个很坑爹的问题 为了更好的用户体验 我希望在项目中 点击返回按键的时候能返回到 某一个指定的页面 返回某些页面的时候页面不缓存 jsp 页面缓存 src 请求缓存 ajax 请求缓存 主要操作的 api 有 pop
  • Ubuntu安装deepin-wine并安装微信

    安装deepin wine 只需要简简单单的三个命令 git clone https gitee com wszqkzqk deepin wine for ubuntu git cd deepin wine for ubuntu insta
  • mysql之union合并查询

    转载链接 http www cnblogs com zzwlovegfj archive 2012 06 23 2559592 html union 联合的意思 即把两次或多次查询结果合并起来 要求 两次查询的列数必须一致 推荐 列的类型可
  • 8.21作业

    双线程拷贝 include
  • IDEA中配置文件格式为UTF-8

    1 第一个需要设置文件编码格式的位置 File gt Settings gt Editor gt File Encodings 2 第二个需要设置文件编码格式的位置 每个项目中的 idea文件夹中的encodings xml文件打开进行文件
  • zTree节点重叠或者遮挡

    ztree官网 http www treejs cn v3 api php 问题 zTree节点重叠或者遮挡 分析 由于zTree和bootstrap插件样式冲突导致的树重叠问题 解决 设置zTreeStyle css文件的 ztree l
  • 机器人比赛对青少年成长的意义

    机器人比赛主要考核参赛选手的实际操作 科学素养 团队合作 创新思维 项目与时间管理和语言表达等能力 格物斯坦小坦克认为以比赛的形式给学生们提供一个交流科学技术的平台 激发学生的潜能 锻炼实际动手能力 培养学生临场随机应变的灵活思维 在提升比
  • 本地部署你的专属ChatGPT,不用想方设法翻墙了

    自ChatGPT问世以来 由于安全问题ChatGTP始终没有在国内提供服务 那访问ChatGTP有条件的就通过专线到国外进行访问 没条件的但喜欢折腾的可以通过各种野路子科学上网 没条件不喜欢折腾的听听就行 无意间在gitHub上发现了一个开
  • MySQL-DDL语句

    MySQL DDL语句 数据库操作语句 增删数据库 查看数据库列表 创建数据库 进入 使用 数据库 查看当前所在的数据库 查看数据库的建库语句 查看数据库的编码集和校验集 删除数据库 修改数据库的编码集 查看数据库支持的编码集和校验集 数据
  • C语言文件操作收尾【随机读写 + 结束判定 + 文件缓冲区】

    全文目录 前言 fseek 重定位位置指示器函数 ftell 获取当前文件指示器的位置 rewind 重置位置指示器 文本文件和二进制文件 文件读取结束的判定 feof 和 ferror 文件缓冲区 总结 前言 有了文件的顺序读写基础 那么
  • 鸿蒙系统是基于linux开发的吗

    鸿蒙系统不是基于linux开发的 而是基于微内核开发的 鸿蒙系统是一款基于微内核面向全场景的分布式操作系统 而Linux是一个单内核结构 同时又吸收了微内核的优点 避免了微内核设计上的缺陷 让一切都运行在内核态 直接调用函数 无需消息传递
  • sql-labs 5-22关(基础关)

    sql lab 第五关 这关是报错注入类型 也可以用盲注 1 判断注入类型 判断闭合方式 1 有回显 1 and 1 1 有回显 1 and 1 2 有回显 1 and 1 2 报错 猜测闭合为单引号 加上注释符 id 1 and 1 1
  • 基于QTreeView和QFileSystemModel,如何做到展开/收缩文件夹分支时改变图标?

    继承QFileSystemModel 添加变量set 重写data和setData函数即可 头文件 public QVariant data const QModelIndex index int role const bool setDa
  • 可重入锁和不可重入锁

    可重入锁 又名递归锁 是指在同一个线程中的在外层方法获取锁的时候 再进入该线程的内层方法会自动获取锁 前提锁对象得是同一个对象或者class 不会应为之前已经获取过还没释放而阻塞 java中ReentrantLock和synchronize
  • Python 爬虫天天基金数据——基金清单

    基金数据目录 1 场外基金清单 列表 2 基金净值 建议直接调用相关API接口 tushare and AKshare 3 业绩排行 4 基金评级 5 基金经理 6 基金公司 1 1关于 场外基金清单 我们可以通过天天基金网或者相关API接
  • windows下创建进程,CreateProcess()详解及用法

    windows下想要创建一个子进程不如linux的fork函数来得方便 通过CreateProcess函数创建一个新的进程 函数的定义如下 cpp view plain copy BOOL CreateProcess LPCTSTR lpA