重启 explorer 进程的正确做法(二)

重启资源管理器进程的方法不唯一,但长期以来大家对实施方法用的不到位。

在上一篇中我认为:“我们往往使用 TerminateProcess 并传入 PID 和特殊结束代码 1 或者 taskkill /f /im 等方法重启资源管理器( explorer.exe ),其实这是不正确的。我们应该使用重启管理器接口来重启 explorer 进程。”

其实,并不能一口咬定以前的方法不正确。我们应该想想为什么 TerminateProcess 似乎必须传入结束代码 1 ,才能不让资源管理器自动重新启动?

要知其然,更要知其所以然。

系列文章:

  • 1.Windows 重启 explorer 的正确做法-CSDN博客
  • 2.重启 explorer 进程的正确做法(二)

在注册表中,有一个叫 “AutoRetartShell” 的注册表值项,该值是 BOOL 类型。当值为 1 时,资源管理器会在结束时通知 Winlogon 并由 Winlogon 自动重新启动 explorer。反之,当该值为 0 时,则不会自动重新启动。

在修改注册表之前,资源管理器在退出时会被自动重启,只有指定特殊的退出状态,才能阻止自动重启。而在修改好注册表后,就不会触发自动重启了。所以,我们正确的做法不是去研究应该用什么进程退出状态码,而是通过临时修改注册表中的关键设置,来屏蔽自动重启功能。

所以,我们正确的做法是,在调用 TerminateProcess 之前,修改注册表 “AutoRetartShell” 的值为 0 ,然后再在结束进程后恢复值为 1 即可。(通常需要管理员权限)

使用下面的代码修改注册表:

/*** @brief 结束 explorer 进程之前,需要首先检查注册表配置** @param[in]       ** @return	TRUE	操作成功完成;*			FALSE	操作失败* @note*/
BOOL SetRegistryValue(LPCWSTR lpSubKey, LPCWSTR lpValueName, DWORD dwData)
{HKEY hKey = NULL;DWORD dwDisposition = 0;//DWORD dwData = bEnable ? 3 : 0; // 默认值为 3,bEnable 作为开关变量// 尝试打开或创建注册表键LONG lResult = RegCreateKeyExW(HKEY_LOCAL_MACHINE,lpSubKey, // L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"0,NULL,REG_OPTION_NON_VOLATILE,KEY_READ | KEY_WRITE,NULL,&hKey,&dwDisposition);if (lResult == ERROR_SUCCESS) {DWORD dwType = 0;DWORD dwValue = 0;DWORD dwSize = sizeof(DWORD);// 检查值是否存在lResult = RegQueryValueExW(hKey, lpValueName,NULL, &dwType, (LPBYTE)&dwValue, &dwSize);if (lResult == ERROR_SUCCESS) {if (dwType == REG_DWORD && dwValue == dwData) {// 值已存在且为 dwData,无需更新RegCloseKey(hKey);return TRUE;}else {// 值存在但不为 dwData,更新值为 dwDatalResult = RegSetValueExW(hKey, lpValueName,  // L"SoftwareSASGeneration"0, REG_DWORD, (BYTE*)&dwData, sizeof(DWORD));RegCloseKey(hKey);return (lResult == ERROR_SUCCESS);}}else if (lResult == ERROR_FILE_NOT_FOUND) {// 值不存在,创建并设置为 dwDatalResult = RegSetValueExW(hKey, lpValueName,0, REG_DWORD, (BYTE*)&dwData, sizeof(DWORD));RegCloseKey(hKey);return (lResult == ERROR_SUCCESS);}else {// 其他错误RegCloseKey(hKey);return FALSE;}}else {// 打开或创建键失败return FALSE;}
}

调用方法如下所示:

if (SetRegistryValue(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",L"AutoRestartShell", 0)) {DWORD dwStatus = 0;if (!TerminateProcess(......)){bResponse = dwStatus;  // 如果调用失败,返回非零错误码}::SetRegistryValue(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",L"AutoRestartShell", 1);
}else {    // 设置注册表失败bResponse = 50037;LogEvent(50037, TEXT("Failed to update LogonType value.\n"));
}

使用 TerminateProcess 结束当前会话的 explorer 进程的代码如下:

#include <Windows.h>
#include <iostream>
#include <WtsApi32.h>#pragma comment(lib, "Wtsapi32.lib")int main()
{PWTS_PROCESS_INFOW process_info;DWORD process_num = 0;DWORD current_session_id = 0;ProcessIdToSessionId(GetCurrentProcessId(), &current_session_id);if (!WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE,0, 1, &process_info, &process_num)){WTSFreeMemory(process_info);return false;}DWORD pid = 0;for (UINT i = 0; i < process_num; i++){if (current_session_id == process_info[i].SessionId && wcscmp(process_info[i].pProcessName, L"explorer.exe") == 0){pid = process_info[i].ProcessId;break;}}WTSFreeMemory(process_info);if (pid != 0){HANDLE hProcessHandle = OpenProcess(PROCESS_TERMINATE, FALSE, pid);if (TerminateProcess(hProcessHandle, 1))  // 修改注册表后,则不需要该值为 1 {CloseHandle(hProcessHandle);return 0;}}return 1;
}

发布于:2024.03.10.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/527234.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贪吃蛇(C语言实现)

贪食蛇&#xff08;也叫贪吃蛇&#xff09;是一款经典的小游戏。 —————————————————————— 本博客实现使用C语言在Windows环境的控制台中模拟实现贪吃蛇小游戏。 实行的基本功能&#xff1a; • 贪吃蛇地图的绘制 • 蛇吃食物的功能&#xff08;上、…

新IDEA电脑环境设置

1.设置UTF-8 2.Maven 3.JRE选对

【NR 定位】3GPP NR Positioning 5G定位标准解读(九)-增强的小区ID定位

前言 3GPP NR Positioning 5G定位标准&#xff1a;3GPP TS 38.305 V18 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;…

Yolov8将.pt文件转换为tensorRt的.trt文件(模型部署)

我的环境 确保自己已经有cuda和cudnn的环境基础上进行。 cuda:11.7cudnn:适合cuda的版本Anaconda3 [python 3.10]TensorRt-8.6.1 安装TensorRt环境 查看自己的cuda环境&#xff0c;去官网下载适合的win版本。 官网地址 下载后解压&#xff0c;将解压后lib目录添加到环境变…

c++0305习题

一、求下面表达式的值 1&#xff0e;0 2&#xff0e;-1 3&#xff0e;1 4&#xff0e;&#xff08;1&#xff09;1 &#xff08;2&#xff09;3.2 &#xff08;3&#xff09;0 &#xff08;4&#xff09;7.0 5.&#xff08;1&#xff09;0&#xff08;2&#xff09;300.005&a…

力扣刷题Day11--21. 合并两个有序链表(js)

目录 1&#xff0c;题目 2&#xff0c;代码 2.1迭代思想 2.2递归思想 3&#xff0c;学习与总结 3.1js中的链表类 3.2递归思想 3.3提醒自己 1&#xff0c;题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 2&am…

trunk

介绍&#xff1a; 在华为企业级网络模拟平台&#xff08;eNSP&#xff09;中&#xff0c;“trunk” 是指用于在交换机之间传送多个 VLAN 数据的端口。在华为设备中&#xff0c;“trunk” 端口实际上就是可以承载多个 VLAN 数据流的端口。 当两台交换机之间需要互相传送多个 VLA…

全面对比Amazon DocumentDB 与 MongoDB

在云中部署 MongoDB 似乎有多种选择。例如&#xff0c;Amazon DocumentDB自称是完全支持 MongoDB API 的 AWS 原生数据库。虽然它支持一些 MongoDB 功能&#xff0c;但需要注意的是 DocumentDB 并不完全兼容 MongoDB。要在 AWS 上访问功能齐全的“MongoDB 即服务”&#xff0c;…

文件操作上(c语言)

目录 1. 文件的作用2. 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 3. 二进制文件和文本文件4. 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开与关闭4.3.1 文件的打开模式4.3.2 实例代码 1. 文件的作用 使用文件可以将数据进行持久化的保…

【50天50个项目】简易进度条

效果: 代码主体: HTML <body><div class"container"><div class"progress-container"><div class"progress" id"progress"></div><div class"circle active">1</div><div …

02-app端文章查看,静态化freemarker,分布式文件系统minIO

app端文章查看&#xff0c;静态化freemarker,分布式文件系统minIO 1)文章列表加载 1.1)需求分析 文章布局展示 1.2)表结构分析 ap_article 文章基本信息表 ap_article_config 文章配置表 ap_article_content 文章内容表 三张表关系分析 1.3)导入文章数据库 1.3.1)导入数据…

golang学习笔记-入门

go build main.go 编译生成 exe go run main.go 直接编译运行 go可以查看官方api源码&#xff0c;在skd安装路径src中 多个import import &#xff08; &#xff09; 字符串用 ~~ ~~反引号&#xff0c;不转义