当前位置: 首页 > news >正文

兰州自媒体公司有哪些兰州seo技术优化排名公司

兰州自媒体公司有哪些,兰州seo技术优化排名公司,怎做连接网站,耳机 东莞网站建设目录 一、关于 Restart Manager 二、重启管理器实例 三、完整实现代码和测试 本文属于原创文章,转载请注明出处: https://blog.csdn.net/qq_59075481/article/details/136179191。 我们往往使用 TerminateProcess 并传入 PID 和特殊结束代码 1 或者…

目录

一、关于 Restart Manager

二、重启管理器实例

三、完整实现代码和测试


本文属于原创文章,转载请注明出处:

https://blog.csdn.net/qq_59075481/article/details/136179191。

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

一、关于 Restart Manager

重启管理器 API 可以消除或减少完成安装或更新所需的系统重启次数。软件更新在安装或更新期间需要重启系统的主要原因是,正在运行的应用程序或服务当前正在使用某些正在更新的文件。 重启管理器允许关闭并重启除关键系统服务外的所有服务 。这会释放正在使用的文件,并允许完成安装操作。

安装程序可以使用重启管理器来注册应在安装应用程序或更新期间替换的文件。然后,在后续更新或安装期间,安装程序可以使用重启管理器来确定哪些文件因当前正在使用而无法更新。重启管理器可以关闭并重启当前使用这些文件的非关键服务或应用程序。安装程序可以指示重启管理器根据正在使用的文件、进程 ID (PID) 或 Windows 服务的短名称来关闭和重启应用程序或服务。

二、重启管理器实例

实现一个简易的重启管理器实例主要需要 RmStartSession 、RmRegisterResources、RmShutdown、RmEndSession 等函数。

首先我们需要在代码中引入头文件:

#include <restartmanager.h>
#pragma comment(lib, "Rstrtmgr.lib")

然后我们用 RmStartSession 创建会话。其中会话的密钥是 GUID ,为其分配缓冲区时候需要计算好缓冲区大小。

#define RM_SESSIONKEY_LEN sizeof(GUID) * 2 + 1
DWORD dwRmStatus = 0;
DWORD dwSessionHandle = 0;
WCHAR strSessionKey[RM_SESSIONKEY_LEN] = { 0 };
dwRmStatus = RmStartSession(&dwSessionHandle, NULL, strSessionKey);
if (ERROR_SUCCESS != dwRmStatus)
{std::cerr << "RmStartSession failed: " << std::dec << dwRmStatus << std::endl;return -1;
}

随后需要将要重启的进程信息放到 RM_UNIQUE_PROCESS 结构体数组中,该结构体如下:

typedef struct _RM_UNIQUE_PROCESS {DWORD    dwProcessId;FILETIME ProcessStartTime;
} RM_UNIQUE_PROCESS, *PRM_UNIQUE_PROCESS;

第一个是进程的 PID,第二个是进程的创建时间,使用 GetProcessTimes 函数的 lpCreationTime 参数获取。

BOOL GetProcessTimes([in]  HANDLE     hProcess,[out] LPFILETIME lpCreationTime,[out] LPFILETIME lpExitTime,[out] LPFILETIME lpKernelTime,[out] LPFILETIME lpUserTime
);

我使用 Toolhelp32 枚举 explorer 进程,并生成 RM_UNIQUE_PROCESS 结构体数组。

BOOL GetShellProcessRmInfoEx(PRM_UNIQUE_PROCESS* lpRmProcList, DWORD_PTR* lpdwCountNum
)
{PROCESSENTRY32W pe32 = { 0 };FILETIME lpCreationTime = { 0 };FILETIME lpExitTime = { 0 };FILETIME lpKernelTime = { 0 };FILETIME lpUserTime = { 0 };HANDLE hProcess = nullptr;RM_UNIQUE_PROCESS tpProc = { 0 };std::vector<RM_UNIQUE_PROCESS> RmProcVec;SIZE_T VecLength = 0;// 在使用这个结构前,先设置它的大小pe32.dwSize = sizeof(pe32);// 给系统内所有的进程拍个快照HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnap == INVALID_HANDLE_VALUE){std::cerr << "CreateToolhelp32Snapshot 调用失败." << std::endl;return FALSE;}// 遍历进程快照,轮流显示每个进程的信息BOOL bMore = Process32FirstW(hProcessSnap, &pe32);while (bMore){if (!_wcsicmp(pe32.szExeFile, L"explorer.exe")){hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe32.th32ProcessID);if (hProcess != nullptr){memset(&lpCreationTime, 0, sizeof(FILETIME));if (GetProcessTimes(hProcess,&lpCreationTime, &lpExitTime,&lpKernelTime, &lpUserTime) == TRUE){tpProc.dwProcessId = pe32.th32ProcessID;tpProc.ProcessStartTime = lpCreationTime;RmProcVec.push_back(tpProc);}CloseHandle(hProcess);hProcess = nullptr;}}bMore = Process32NextW(hProcessSnap, &pe32);}// 清除 snapshot 对象CloseHandle(hProcessSnap);VecLength = RmProcVec.size();if (VecLength != 0 && VecLength < (SIZE_T)0xf4236u){RM_UNIQUE_PROCESS* lprmUniqueProc = new(std::nothrow) RM_UNIQUE_PROCESS[VecLength];if (lprmUniqueProc != nullptr){SIZE_T rSize = VecLength * sizeof(RM_UNIQUE_PROCESS);if (rSize < (SIZE_T)0xC80000u && rSize > 0){if (!memcpy_s(lprmUniqueProc, rSize, &RmProcVec[0], rSize)){*lpdwCountNum = VecLength;*lpRmProcList = lprmUniqueProc;return TRUE;}}else {std::cerr << "Vector Size to large!" << std::endl;}}else {std::cerr << "Alloc memory failed!" << std::endl;}}else {std::cerr << "Vector Size to large!" << std::endl;}return FALSE;
}

使用 RmRegisterResources 函数将资源注册到重启管理器会话。重启管理器使用向会话注册的资源列表来确定必须关闭和重启哪些应用程序和服务。 可以通过文件名、服务短名称或描述正在运行的应用程序 RM_UNIQUE_PROCESS 结构来标识资源。参数解释如下:

参数解释

代码如下: 

dwRmStatus = RmRegisterResources(dwSessionHandle,0, NULL, dwNum, lpRmProcList, 0, NULL);
if (ERROR_SUCCESS != dwRmStatus)
{std::cerr << "RmRegisterResources failed: " << std::dec << dwRmStatus << std::endl;RmProcMemFree(lpRmProcList, lpdwCountNum);return -1;
}

然后使用 RmShutdown 就可以请求结束进程,可以指定第二个参数来选择强制或者非强制两种状态。

完成任务后使用 RmRestart 重新启动被关闭的进程即可,程序会尝试恢复并刷新状态。

所有操作完成后,使用 RmEndSession 关闭会话句柄。

三、完整实现代码和测试

完整代码如下:

#include <iostream>
#include <Windows.h>
#include <restartmanager.h>
#include <TlHelp32.h>
#include <vector>#pragma comment(lib, "Rstrtmgr.lib")#define RM_SESSIONKEY_LEN sizeof(GUID) * 2 + 1BOOL GetShellProcessRmInfoEx(PRM_UNIQUE_PROCESS* lpRmProcList,DWORD_PTR* lpdwCountNum
);
void RmProcMemFree(PRM_UNIQUE_PROCESS lpRmProcList,DWORD_PTR lpdwCountNum
);void RmWriteStatusCallback(UINT nPercentComplete
);int main()
{DWORD dwRmStatus = 0;DWORD dwSessionHandle = 0;WCHAR strSessionKey[RM_SESSIONKEY_LEN] = { 0 };dwRmStatus = RmStartSession(&dwSessionHandle, NULL, strSessionKey);if (ERROR_SUCCESS != dwRmStatus){std::cerr << "RmStartSession failed: " << std::dec << dwRmStatus << std::endl;return -1;}PRM_UNIQUE_PROCESS lpRmProcList = nullptr;DWORD_PTR lpdwCountNum = 0;if (!GetShellProcessRmInfoEx(&lpRmProcList, &lpdwCountNum)){std::cerr << "GetShellProcessRmInfoEx failed."<< std::endl;return -1;}UINT dwNum = static_cast<UINT>(lpdwCountNum);std::cout << "Process Count: " << dwNum << std::endl;std::cout << "Shell PID: "<< std::endl;for (UINT i = 0; i < dwNum; i++){std::cout << " > " << lpRmProcList[i].dwProcessId << std::endl;}dwRmStatus = RmRegisterResources(dwSessionHandle,0, NULL, dwNum, lpRmProcList, 0, NULL);if (ERROR_SUCCESS != dwRmStatus){std::cerr << "RmRegisterResources failed: " << std::dec << dwRmStatus << std::endl;RmProcMemFree(lpRmProcList, lpdwCountNum);return -1;}dwRmStatus = RmShutdown(dwSessionHandle, RmForceShutdown, RmWriteStatusCallback);if (ERROR_SUCCESS != dwRmStatus){std::cerr << "RmShutdown failed: " << std::dec << dwRmStatus << std::endl;// return -1;}Sleep(5000);dwRmStatus = RmRestart(dwSessionHandle, 0, RmWriteStatusCallback);if (ERROR_SUCCESS != dwRmStatus){std::cerr << "RmRestart failed: " << std::dec << dwRmStatus << std::endl;// return -1;}dwRmStatus = RmEndSession(dwSessionHandle);if (ERROR_SUCCESS != dwRmStatus){std::cerr << "RmEndSession failed: " << std::dec << dwRmStatus << std::endl;// return -1;}RmProcMemFree(lpRmProcList, lpdwCountNum);return 0;
}void RmWriteStatusCallback(UINT nPercentComplete
)
{std::cout << "Task completion level: " << std::dec << nPercentComplete << std::endl;
}BOOL GetShellProcessRmInfoEx(PRM_UNIQUE_PROCESS* lpRmProcList, DWORD_PTR* lpdwCountNum
)
{PROCESSENTRY32W pe32 = { 0 };FILETIME lpCreationTime = { 0 };FILETIME lpExitTime = { 0 };FILETIME lpKernelTime = { 0 };FILETIME lpUserTime = { 0 };HANDLE hProcess = nullptr;RM_UNIQUE_PROCESS tpProc = { 0 };std::vector<RM_UNIQUE_PROCESS> RmProcVec;SIZE_T VecLength = 0;// 在使用这个结构前,先设置它的大小pe32.dwSize = sizeof(pe32);// 给系统内所有的进程拍个快照HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnap == INVALID_HANDLE_VALUE){std::cerr << "CreateToolhelp32Snapshot 调用失败." << std::endl;return FALSE;}// 遍历进程快照,轮流显示每个进程的信息BOOL bMore = Process32FirstW(hProcessSnap, &pe32);while (bMore){if (!_wcsicmp(pe32.szExeFile, L"explorer.exe")){hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe32.th32ProcessID);if (hProcess != nullptr){memset(&lpCreationTime, 0, sizeof(FILETIME));if (GetProcessTimes(hProcess,&lpCreationTime, &lpExitTime,&lpKernelTime, &lpUserTime) == TRUE){tpProc.dwProcessId = pe32.th32ProcessID;tpProc.ProcessStartTime = lpCreationTime;RmProcVec.push_back(tpProc);}CloseHandle(hProcess);hProcess = nullptr;}}bMore = Process32NextW(hProcessSnap, &pe32);}// 清除 snapshot 对象CloseHandle(hProcessSnap);VecLength = RmProcVec.size();if (VecLength != 0 && VecLength < (SIZE_T)0xf4236u){RM_UNIQUE_PROCESS* lprmUniqueProc = new(std::nothrow) RM_UNIQUE_PROCESS[VecLength];if (lprmUniqueProc != nullptr){SIZE_T rSize = VecLength * sizeof(RM_UNIQUE_PROCESS);if (rSize < (SIZE_T)0xC80000u && rSize > 0){if (!memcpy_s(lprmUniqueProc, rSize, &RmProcVec[0], rSize)){*lpdwCountNum = VecLength;*lpRmProcList = lprmUniqueProc;return TRUE;}}else {std::cerr << "Vector Size to large!" << std::endl;}}else {std::cerr << "Alloc memory failed!" << std::endl;}}else {std::cerr << "Vector Size to large!" << std::endl;}return FALSE;
}void RmProcMemFree(PRM_UNIQUE_PROCESS lpRmProcList, DWORD_PTR lpdwCountNum)
{__try{DWORD_PTR dwCountNum = lpdwCountNum;if (lpRmProcList != nullptr && dwCountNum > 0){while (--dwCountNum){if (IsBadWritePtr(&lpRmProcList[dwCountNum], sizeof(RM_UNIQUE_PROCESS))){throw(L"BadWritePtr event!");break;}memset(&lpRmProcList[dwCountNum], 0, sizeof(RM_UNIQUE_PROCESS));}delete[] lpRmProcList;}}__except (EXCEPTION_EXECUTE_HANDLER){// 处理 SEH 异常std::cerr << "Error access violation." << std::endl;exit(-1);}
}

测试效果如图所示:

测试结果截图

测试内容:首先结束所有 explorer 进程,随后重启进程。 


本文属于原创文章,转载请注明出处:

https://blog.csdn.net/qq_59075481/article/details/136179191。

文章发布于:2024.02.19,更新于:2024.02.19.

http://www.hkea.cn/news/530890/

相关文章:

  • 网站建设需要学什么网站模板购买
  • 用html做的游戏网站关键词推广效果分析
  • 做影视网站引流正规推广平台有哪些
  • 免费下载简历模板北京seo排名厂家
  • 西昌市做网站的百度搜索排名靠前
  • 办公室装修实景拍摄图重庆seo俱乐部联系方式
  • 网站建设阶段推广计划书怎么写
  • 代做毕业设计网站现成注册网站平台
  • 电商网站开发工作计划企业网络营销策划
  • 用wps网站栏目做树形结构图网页设计代码案例
  • 多媒体网站设计开发是指什么每日关键词搜索排行
  • 网站 seo正规网络公司关键词排名优化
  • 建立网站赚多少钱seo收录排名
  • 怎么做app网站seo学习网站
  • 广西建设职业技术学院官网免费的seo优化
  • 凡科网电脑版怎么做网站百度知道官网手机版
  • 贵卅省住房和城乡建设厅网站周口seo推广
  • 搭建flv视频网站seo工具查询
  • 企业展示网站 数据库设计模板自助建站
  • 房地产设计师上海seo网络优化
  • wordpress迁移打不开百度seo泛解析代发排名
  • 网站兼容性测试怎么做微信营销软件群发
  • wordpress如何设置内容页seo营销优化
  • 高端大气的网站制作南宁百度seo软件
  • 沙井营销型网站建设成人培训机构
  • 网站没有被百度收录搜索引擎排名优化公司
  • 手机网站转换小程序晋江怎么交换友情链接
  • 专业做网站的公司疫情放开最新消息今天
  • 不用写代码做网站软件长沙优化网站
  • o2o商城网站建设方案广告策划案优秀案例