进程有启动就有终止,通过CreateProcess函数可以启动一个新的子进程,但是如何终结子进程呢?主要有四种方法:

通过主线程的入口函数(main函数、WinMain函数)的return关键字终止进程

一个应用程序只有一个入口函数,对于控制台来说是main函数,对于GUI程序来说这个入口函数一般是WinMain。入口函数通过return关键字返回或者程序自上而下执行完成之后,进程可以自动终止,进程相关的所有资源都会被操作清理。这也是开发中最常用的进程终止方法,也是强烈推荐大家使用的终止进程的方式。

那么如何能获取到子进程的返回值呢,以下面代码为例,这是一个最简单的控制台程序,它返回-3。

#include <iostream>
#include <Windows.h>
int main()
{
return -3;
}

首先演示在cmd控制台或者bat脚本中如何获取该进程的最终返回值:通过echo %errorlevel%命令可以获取到上一个cmd命令的返回值。如下:

在程序中获取子进程的返回值,CreateProcess函数创建子进程成功之后,主进程可以拿到子进程的句柄。通过调用GetExitCodeProcess函数可以获取到某个进程的返回值,函数原型如下:

BOOL GetExitCodeProcess(
HANDLE hProcess,//子进程句柄
LPDWORD lpExitCode//用于接受子进程的返回值
);

请看以下代码:

#include <iostream>
#include <Windows.h>
int main()
{
//即将启动的exe程序路径
LPCWSTR lpApplicationName = L"D:\\project\\ConsoleApp1\\x64\\Debug\\NewApp.exe"; // 定义启动信息和进程信息结构
STARTUPINFOW si;
PROCESS_INFORMATION pi; // 初始化启动信息结构
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi)); BOOL ret = CreateProcess(lpApplicationName,
NULL,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
// 等待进程结束
WaitForSingleObject(pi.hProcess, INFINITE); // 获取子进程的返回值
DWORD exitCode;
GetExitCodeProcess(pi.hProcess, &exitCode);
// 将无符号整数转换为有符号整数
int signedExitCode = static_cast<int>(exitCode);
std::cout << "Child process exited with code: " << signedExitCode << std::endl;
return 0;
}

主程序在创建子进程之后,首先调用WaitForSingleObject等待子进程结果,然后调用GetExitCodeProcess函数获取子进程的返回值。但是这里注意,如果子进程返回0或者正数是没问题的,因为DWORD是一个无符号的整数类型,但是如果子进程返回负数的话,就需要我们手动将无符号整数转换为有符号整数。最后执行结果如下,可以看到正常获取到了子进程的返回值。

通过ExitProcess函数终止进程

ExitProcess函数可以终止进程,并且会设置一个进程的返回值。该函数原型只有一个参数,就是进程的返回值:

void ExitProcess(
UINT uExitCode //进程返回值
);

注意:调用ExitProcess之后,进程会直接退出,ExitProcess之后的函数都不会继续执行,在程序中,一定要尽量避免直接调用这个函数,我们以下面的代码为例:

#include <iostream>
#include <Windows.h>
int main(int argc, char** argv)
{
ExitProcess(-4);
std::cout << "Hello World!" << std::endl;
return -3;
}

当我们双击编译好的控制台程序之后,会发现hello World!并没有被执行,并且成功的返回了-4,效果如下:

通过TerminateProcess函数终止进程

我们首先来修改子进程程序,通过一个无限while循环使进程永远不会退出:

#include <iostream>
#include <Windows.h>
int main(int argc, char** argv)
{
while (true) {
std::cout << "Hello World!" << std::endl;
Sleep(1000);
}
}

然后按照上面的代码,创建完子进程之后,我们可以调用TerminateProcess函数直接终止子进程。

	BOOL ret = CreateProcess(lpApplicationName,
NULL,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi); TerminateProcess(pi.hProcess, -3);

TerminateProcess函数非常的简单粗暴,会强制将子进程终结,也应该尽量避免直接调用该函数终止进程,只有在其他办法都无法强制终结子进程的情况下,才可以使用该函数强制终结进程。

Windows编程----结束进程的更多相关文章

  1. Windows编程之进程遍历(C++实现)

    Windows编程之进程遍历 PS: 主要扣代码使用,直接滑动到最下面使用. 遍历进程需要几个API,和一个结构体 1.创建进程快照 2.遍历首次进程 3.继续下次遍历 4.进程信息结构体 API 分 ...

  2. Windows下查看进程及结束进程命令[转]

    Windows下查看进程及结束进程命令 1)查看占用8080端口的进程号 >netstat –aon | findstr “8080” 结果:TCP    0.0.0.0:8080        ...

  3. Windows下查看8080进程及结束进程命令

    Windows下查看进程及结束进程命令 1)查看占用8080端口的进程号 >netstat –aon | findstr “8080” 结果:TCP    0.0.0.0:8080        ...

  4. windows 结束进程的详细过程

    windows上如何结束进程的详细过程,下面附详细,图文说明 在cmd下,输入  netstat   -ano|findstr  8080      //说明:查看占用8080端口的进程 在cmd下, ...

  5. windows编程 进程的创建销毁和分析

    Windows程序设计:进程 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,在Windows编程环境下,主要由两大元素组成: • 一个是操作系统用来管理进程的内核对象.操作系统使用内 ...

  6. windows查看端口占用、结束进程

    在开发中难免会遇到windows的端口被占用,现在我们来查看端口的占用和结束占用端口的进程. win+r 输入cmd进入命令提示符: 比如我们要查看8080端口的占用情况,输入netstat -aon ...

  7. git for windows 无法结束node进程(windows下杀进程)

    问题 windows 系统下,如果用CMD命令行启动node服务,Ctrl + C 即可结束命令 git bash 用起来比命令行方便,但是Ctrl + C 并不会结束node服务,再次启动会报如下错 ...

  8. windows下查看进程及结束进程命令

    windows下查看进程及结束进程命令 1)查看占用8080端口的进程号 >netstat –aon | findstr “8080” 结果:TCP    0.0.0.0:8080        ...

  9. Linux编程 7 (实时监测进程 top, 结束进程kill,killall)

    一. 实时监测进程 top 在一篇里讲到ps命令在收集进程信息时非常有用,但它只能显示某个特定时间点的信息.想要观察那些频繁换进换出的内存进程趋势,用top命令是合适的.使用top命令如下图所示: 在 ...

  10. Win64 驱动内核编程-26.强制结束进程

    强制结束进程 依然已经走到驱动这一层了,那么通常结束掉一个进程不是什么难的事情.同时因为win64 位的各种保护,导致大家慢慢的已经不敢HOOK了,当然这指的是产品.作为学习和破解的话当然可以尝试各种 ...

随机推荐

  1. 区分PO、VO、 BO、 DTO、 POJO

      分层领域模型规约: DO(Data Object):此结构与数据库表结构一一对应,通过DTO向上传输数据源对象. DTO(Data Transfer Object):数据传输对象,Service ...

  2. Qt音视频开发14-音视频文件保存基类的设计

    一.前言 视频综合应用示例,包括了多种内核,在保存文件这个功能上,需要一个通用的文件保存基类AbstractSaveThread,这个基类定义了是否打印线程消息标志位.直接写入还是排队写入标志位.文件 ...

  3. Qt编写物联网管理平台33-设备面板

    一.前言 设备面板展示数据,相对于表格展示,可能在一个页面中能够展示的设备数据量少一些,但是有些用户和场景,又需要这种面板的形式,可能更生动形象一些.尤其是经过这么些年的社会的毒打,我的原则是:用户是 ...

  4. 模拟数据生成器mock.js入门

    1.在某一指定目录下,按下shift+鼠标右键,,点击"在此处打开Powershell窗口(S)",启动命令行窗口.如下图: 2.在窗口中输入以下命令以便创建项目:vue crea ...

  5. 即时通讯技术文集(第40期):推送技术合集(Part2) [共18篇]

    为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第 40 期. [- 1 -] 一个基于长连接的安全可扩展的订阅/推送服务实现思路 [链接] h ...

  6. 即时通讯安全篇(九):为什么要用HTTPS?深入浅出,探密短连接的安全性

    本文由ELab技术团队分享,原题"探秘HTTPS",有修订和改动. 1.引言 对于IM开发者来说,IM里最常用的通信技术就是Socket长连接和HTTP短连接(通常一个主流im会是 ...

  7. 关于存入sessionStorage中boolean值拿出来为字符串

    上面是html部分,然后定义了变量 定义方法 在mounted中获取,然后刷新页面,打印类型为字符串 解决办法

  8. TestProject 使用汇总

    1. 截图 from addons.screenshot_utils import ScreenshotUtils step_output = driver.addons().execute( Scr ...

  9. Solution Set - “潮汐守候终结放逐月圆”

    目录 0.「NOI Simu.」游戏 1.「NOI Simu.」海盗 2.「集训队作业 2020-2021」「LOJ #3405」Gem Island 2 3.「UR #12」「UOJ #181」密码 ...

  10. Python 潮流周刊#85:让 AI 帮你写出更好的代码(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...