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

MFC实现守护进程,包括开机自启动、进程单例、进程查询、进程等待、重启进程、关闭进程

        在Windows平台上实现一个守护进程,由于与系统有关,所有使用MFC来实现是最合适的,被守护的进程则不限语言。废话不多,直接开整。

目录

1. 开机自启动

2. 进程单例

3. 进程查询

4. 进程等待

5. 重启进程

6. 关闭进程

7、最后的最后


1. 开机自启动

        守护进程自然要开机自启动。

//设置自身开机启动
BOOL SetSelfStart()
{//获取程序完整名称char pName[MAX_PATH] = { 0 };GetModuleFileNameA(NULL, pName, MAX_PATH);//在注册表中写入启动信息HKEY hKey = NULL;LONG lRet = NULL;lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SELFSTART_REGEDIT_PATH, 0, KEY_ALL_ACCESS, &hKey);//判断是否成功if (lRet != ERROR_SUCCESS){return FALSE;}lRet = RegSetValueExA(hKey, "w10_daemon", 0, REG_SZ, (const unsigned char*)pName, strlen(pName) + sizeof(char));//判断是否成功if (lRet != ERROR_SUCCESS){return FALSE;}//关闭注册表RegCloseKey(hKey);return TRUE;
}

2. 进程单例

        也就是防止软件被多次启动,在需要长时间无人值守运行的软件中,不管守护进程或者被守护进程都不希望软件启动多次。

BOOL InitInstance()
{LPCWSTR pszExeName = L"GuardApplication";        //    使用软件自身的名称// 用应用程序名创建信号量HANDLE hSem = CreateSemaphore(NULL, 1, 1, pszExeName);// 信号量已存在?// 信号量存在,则程序已有一个实例运行if (GetLastError() == ERROR_ALREADY_EXISTS){// 关闭信号量句柄CloseHandle(hSem);return FALSE;// 寻找先前实例的主窗口HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);while (::IsWindow(hWndPrevious)){// 检查窗口是否有预设的标记?// 有,则是我们寻找的主窗if (::GetProp(hWndPrevious, pszExeName)){// 主窗口已最小化,则恢复其大小if (::IsIconic(hWndPrevious))::ShowWindow(hWndPrevious, SW_RESTORE);// 将主窗激活::SetForegroundWindow(hWndPrevious);// 将主窗的对话框激活::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));// 退出本实例return FALSE;}// 继续寻找下一个窗口hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);}// 前一实例已存在,但找不到其主窗// 可能出错了// 退出本实例return FALSE;}return TRUE;
}

3. 进程查询

        守护进程,自然需要找到被守护的进程id等信息。

BOOL IsExistProcess(CONST WCHAR* szProcessName, DWORD& ProcessID)
{PROCESSENTRY32 processEntry32;HANDLE toolHelp32Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (((int)toolHelp32Snapshot) != -1){processEntry32.dwSize = sizeof(processEntry32);if (Process32First(toolHelp32Snapshot, &processEntry32)){do{if (wcscmp(szProcessName, processEntry32.szExeFile) == 0){ProcessID = processEntry32.th32ProcessID;return TRUE;}} while (Process32Next(toolHelp32Snapshot, &processEntry32));}CloseHandle(toolHelp32Snapshot);}return FALSE;
}

4. 进程等待

        查寻到进程号之后,最好的办法就是等待它退出,而不是定时重复查询。

HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, processEntry32.th32ProcessID);
if (hProcess != NULL) {WaitForSingleObject(hProcess, INFINITE);CloseHandle(hProcess);
}

5. 重启进程

        被守护的进程消失了怎么办?当然是重启该进程喽。

WCHAR* pCmd = L"cmd /c D:\\test\\abcd.exe";STARTUPINFOW si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;//进程对象
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));//创建子进程,判断是否执行成功
if (!CreateProcessW(NULL, pCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{cout << "守护进程启动失败,程序即将退出" << endl;return 0;
}// 等待进程启动
WaitForInputIdle(pi.hProcess, 10000);// 获取进程窗口句柄
HWND hWnd = FindWindow(NULL, PROCCESS_NAME);
if (hWnd)
{// 将进程窗口置顶SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);// 给予焦点SetForegroundWindow(hWnd);
}

6. 关闭进程

        为什么还要关闭进程呢?当然是需要正常关闭其他进程的时候去做了,比如:被守护的进程不想被守护了,自然需要先杀掉守护进程,再然后自杀。

//利用查找到的进程ID,打开进程:
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processEntry32.th32ProcessID);//关闭进程
BOOL bRet = TerminateProcess(hProcess, 0);CloseHandle(hProcess);

7、最后的最后

        当然是附上守护进程软件的源码链接了,开源就要彻底,你都看到这了,还不给我点个赞,加个关注吗?就算白嫖也要自觉一点,不是吗?当然能给我打个赏我就万分感谢了!

这是下载链接

相关文章:

MFC实现守护进程,包括开机自启动、进程单例、进程查询、进程等待、重启进程、关闭进程

在Windows平台上实现一个守护进程&#xff0c;由于与系统有关&#xff0c;所有使用MFC来实现是最合适的&#xff0c;被守护的进程则不限语言。废话不多&#xff0c;直接开整。 目录 1. 开机自启动 2. 进程单例 3. 进程查询 4. 进程等待 5. 重启进程 6. 关闭进程 7、最后…...

Spark SQL数据源 - Parquet文件

当使用Spark SQL处理Parquet文件时&#xff0c;你可以使用spark.read.parquet()方法从文件系统中加载Parquet数据到一个DataFrame中。Parquet是一种列式存储格式&#xff0c;非常适合用于大数据集&#xff0c;因为它提供了高效的压缩和编码方案。 以下是一个简单的例子&#x…...

eNsp——两台电脑通过一根网线直连通信

一、拓扑结构 二、电脑配置 ip和子网掩码&#xff0c;配置两台电脑处于同一网段 三、测试 四、应用 传文件等操作&#xff0c;可以在一台电脑上配置FTP服务器...

杂牌记录仪TS视频流恢复方法

大多数的记录仪都采用了MP4/MOV文件方案&#xff0c;极少数的可能在用AVI文件&#xff0c;极极少数的在用TS文件方案。很多人可能不太解TS文件&#xff0c;这是一种古老的视频文件结构&#xff0c;下边这个案例我们来看下TS视频文件的恢复方法。 故障存储:8G存储卡/fat32文件系…...

十_信号7-信号集

int sigemptyset(sigset_t *set); 清空信号集 int sigfillset(sigset_t *set); 填充满 信号集 int sigaddset(sigset_t *set, int signum); 向信号集中添加信号 int sigdelset(sigset_t *set, int signum); 从型号集中删除信号 int sigismember(const sigset_t *set, int s…...

GPT-4o

微软最新发布的CopilotPC采用了OpenAI最新的GPT-4o技术&#xff0c;新增了多项强大功能。以下是主要的新增功能&#xff1a; 更强大的AI处理能力&#xff1a;CopilotPC采用了专门用于AI处理的特殊芯片&#xff0c;使得电脑能够处理更多的人工智能任务&#xff0c;而无需调用云…...

32位与64位程序下函数调用的异同——计科学习中缺失的内容

前言 今天&#xff0c;通过一个有趣的案例&#xff0c;从反编译的角度看一下C语言中函数参数是如何传递的。 创建main.c文件&#xff0c;将下面实验代码拷贝到main.c文件中。 # main.c #include <stdio.h>int test(int a, int b, int c, int d, int e, int f, int g, …...

Python爬虫实战(实战篇)—16获取【百度热搜】数据—写入Ecel(附完整代码)

文章目录 专栏导读背景结果预览1、爬取页面分析2、通过返回数据发现适合利用lxmlxpath3、继续分析【小说榜、电影榜、电视剧榜、汽车榜、游戏榜】4、完整代码总结 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门…...

js切割数组的两种方法slice(),splice()

slice() 返回一个索引和另一个索引之间的数据(不改变原数组),slice(start,end)有两个参数(start必需,end选填),都是索引,返回值不包括end 用法和截取字符串一样 splice() 用来添加或者删除数组的数据,只返回被删除的数据,类型为数组(改变原数组) var heroes["李白&q…...

【计算机毕设】基于SpringBoot的医院管理系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 本项目旨在设计并实现一个基于SpringBoot的医院管理系统&#xff0c;以提高医院管理效率&#xff0c;优化医疗服务流程&#xff0c;提升患者就诊体验…...

导线防碰撞警示灯:高压线路安全保障

导线防碰撞警示灯&#xff1a;高压线路安全保障 在广袤的大地上&#xff0c;高压线路如同血脉般纵横交错&#xff0c;然而&#xff0c;在这看似平静的电力输送背后&#xff0c;却隐藏着不容忽视的安全隐患。特别是在那些输电线路跨越道路、施工等区域的路段&#xff0c;线下超…...

【LeetCode 77. 组合】

1. 题目 2. 分析 本题有个难点在于如何保存深搜得到的结果&#xff1f;总结了一下&#xff0c;深搜处理的代码&#xff0c;关于返回值有三大类。 第一类&#xff1a;层层传递&#xff0c;将最深层的结果传上来&#xff1b;这类题有&#xff1a;【反转链表】 第二类&#xff1…...

element-ui组件table去除下方滚动条,实现鼠标左右拖拽移动表格

时隔多日&#xff0c;再次遇到值得记录的问题。 需求 项目前端使用vue框架&#xff0c;页面使用element-ui进行页面快速搭建。默认的table组件当表格过长时&#xff0c;下方会出现横向的滚动条&#xff0c;便于用户对表格进行左右滑动。考虑到页面美观问题&#xff0c;滚动条…...

【C++】list的使用(上)

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 前言&#x1f308;关于list&#x1f525;默认成员函数构造函数&#xff08;constructor&#xff09;析构函数&#xff08;destructor&#xff09;赋值运算符重载 &#x1…...

【代码随想录训练营】【Day 37】【贪心-4】| Leetcode 840, 406, 452

【代码随想录训练营】【Day 37】【贪心-4】| Leetcode 840, 406, 452 需强化知识点 python list sort的高阶用法&#xff0c;两个key&#xff0c;另一种逆序写法python list insert的用法 题目 860. 柠檬水找零 思路&#xff1a;注意 20 块找零&#xff0c;可以找3张5块升…...

concat是什么?前端开发者必须掌握的数组拼接利器

concat是什么&#xff1f;前端开发者必须掌握的数组拼接利器 在前端开发中&#xff0c;concat是一个极其重要的概念&#xff0c;它能够帮助我们实现数组之间的无缝拼接。那么&#xff0c;concat到底是什么&#xff1f;为什么它在前端开发中如此重要&#xff1f;接下来&#xf…...

WHAT - 容器化系列(一)

这里写目录标题 一、什么是容器与虚拟机1.1 什么是容器1.2 容器的特点1.3 容器和虚拟机的区别虚拟机&#xff08;VM&#xff09;&#xff1a;基于硬件的资源隔离技术容器&#xff1a;基于操作系统的资源隔离技术对比总结应用场景 二、容器的实现原理1. Namespace&#xff08;命…...

QT7_视频知识点笔记_67_项目练习(页面以及对话框的切换,自定义数据类型,DB数据库类的自定义及使用)

视频项目&#xff1a;7----汽车销售管理系统&#xff08;登录&#xff0c;品牌车管理&#xff0c;新车入库&#xff0c;销售统计图表&#xff09;-----项目视频没有&#xff0c;代码也不全&#xff0c;更改项目练习&#xff1a;学生信息管理系统。 学生信息管理系统&#xff1…...

windows10系统64位安装delphiXE11.2完整教程

windows10系统64位安装delphiXE11.2完整教程 https://altd.embarcadero.com/download/radstudio/11.0/radstudio_11_106491a.iso XE11.1 https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso XE11.2 关键使用文件在以下内容&#xff1a;windows10…...

09.责任链模式

09. 责任链模式 什么是责任链设计模式&#xff1f; 责任链设计模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将请求沿着处理者对象组成的链进行传递&#xff0c;直到有一个处理者对象能够处理该请求为止。这种模式的目的…...

Amazon云计算AWS(一)

目录 一、基础存储架构Dynamo&#xff08;一&#xff09;Dynamo概况&#xff08;二&#xff09;Dynamo架构的主要技术 二、弹性计算云EC2&#xff08;一&#xff09;EC2的基本架构&#xff08;二&#xff09;EC2的关键技术&#xff08;三&#xff09;EC2的安全及容错机制 提供的…...

十_信号4-SIGCHLD信号

SIGCHLD信号 在学习进程控制的时候&#xff0c;使用wait和waitpid系统调用何以回收僵尸进程&#xff0c;父进程可以阻塞等待&#xff0c;也可以非阻塞等待&#xff0c;采用轮询的方式不停查询子进程是否退出。 采用阻塞式等待&#xff0c;父进程就被阻塞了&#xff0c;什么都干…...

HCIP的学习(27)

RSTP—802.1W—快速生成树协议 STP缺陷&#xff1a; 1、收敛速度慢----STP的算法是一种被动的算法&#xff0c;依赖于计时器来进行状态变化 2、链路利用率低​ RSTP向下兼容STP协议。&#xff08;STP不兼容RSTP&#xff09; 改进点1—端口角色 802.1D协议---根端口、指定端口…...

6. MySQL 查询、去重、别名

文章目录 【 1. 数据表查询 SELECT 】1.1 查询表中所有字段使用 * 查询表的所有字段列出表的所有字段 1.2 查询表中指定的字段 【 2. 去重 DISTINCT 】【 3. 设置别名 AS 】3.1 为表指定别名3.2 为字段指定别名 【 5. 限制查询结果的条数 LIMIT 】5.1 指定初始位置5.2 不指定初…...

Oracle导出clob字段到csv

使用UTL_FILE ref: How to Export The Table with a CLOB Column Into a CSV File using UTL_FILE ?(Doc ID 1967617.1) --preapre data CREATE TABLE TESTCLOB(ID NUMBER, MYCLOB1 CLOB, MYCLOB2 CLOB ); INSERT INTO TESTCLOB(ID,MYCLOB1,MYCLOB2) VALUES(1,Sample row 11…...

C++无锁(lock free)队列moodycamel::ConcurrentQueue

moodycamel::ConcurrentQueue介绍 moodycamel::ConcurrentQueue一个用C++11实现的多生产者、多消费者无锁队列。 它具有以下特点: 1.快的让人大吃一惊,详见不同无锁队列之间的压测对比 2.单头文件实现,很容易集成到你的项目中 3.完全线程安全的无锁队列,支持任意线程数的并…...

python办公自动化——(二)替换PPT文档中图形数据-柱图

效果: 数据替换前 &#xff1a; 替换数据后&#xff1a; 实现代码 import collections.abc from pptx import Presentation from pptx.util import Cm,Pt import pyodbc import pandas as pd from pptx.chart.data impo…...

vue不同页面切换的方式(Vue动态组件)

v-if实现 <!--Calender.vue--> <template><a-calendar v-model:value"value" panelChange"onPanelChange" /></template> <script setup> import { ref } from vue; const value ref(); const onPanelChange (value, mod…...

Linux下Qt Creator无法输入中文(已解决)

1. 首先确保安装了搜狗输入法&#xff0c;且能正常运行。 2.克隆源码到本地。 git clone https://gitcode.com/fcitx/fcitx-qt5.git 3.检查Qt Creator版本&#xff0c;如下图所示&#xff0c;为基于Qt6的。 4. 进入源码目录&#xff0c;建立build文件夹&#xff0c;修改CMak…...

Codeforces 提交Java代码(自己处理输入输出)

示例一&#xff08;A. Watermelon&#xff09; 题目地址 Problem - 4A - Codeforces 题目截图 提交方式 可以提交本地文件&#xff0c;也可以在线提交。我们这里选择在线提交方式&#xff0c;点击上图中的 SUBMIT 按钮&#xff0c;会进入如下界面。 输入Java代码效果如下&a…...