C# 关于进程回收管理的一款工具设计与分享

目录

设计初衷

开发运行环境

Craneoffice ProcessGC

运行主界面

管理任务与策略

其它设置

移动存储设备管理

核心代码-计时器监控

小结


设计初衷

在使用 COM 模式操作 OFFICE 组件的开发过程中,当操作完相关文档后,在某些情况下仍然无法释放掉 Word 或 EXCEL 等应用进程,因此根据进程活动情况或时间点范围开发了一个强制杀掉指定进程名称的 WinForm 程序,做为一种辅助工具运行在云服务器上,命名为 Craneoffice ProcessGC。

开发运行环境

操作系统: Windows Server 2019 DataCenter

.net版本: .netFramework4.0 或以上

开发工具:VS2019  C#

Craneoffice ProcessGC

该工具软件属绿色版,无须安装,直接运行 bin 目录下的 ProcessGC.exe 即可,同目录下的 ProcessList.txt 为配置文件,用于配置要释放的进程,后续也可用工具程序进行操作。

运行主界面

运行后的主界面如下图:

主界面显示了要回收的进程列表,源引于 ProcessList.txt 文件配置,如图示例我们可以看到欲回收的进程为EXCEL和WORD,下面则显示已被回收的进程(如果有的话)。

下方显示 CPU 的利用率和可用内存情况。

系统会随时监测指定的进程名,如果有则按指定的策略进行管理。

管理任务与策略

点击管理任务选项卡,显示如下图:

策略设置如下表:

序号说明
1要添加回收的进程名请正确添加,无须输入扩展名,如果不确定名称则可以通过任务管理器进行查看
2管理策略

共分三种方式:

1、Force(默认值,表示符合条件则强制关闭)

2、CPU

3、Memory

3回收时间差(秒)以秒为单位,记录进程停止活动的时间,超过停止活动时间的进程将被回收
4上限指标

1、上限指标不能小于零。

2、当选用的策略为CPU时,上限指标不能大于100(即最高100%占用率)

3、当选用的策略为Memory时,指定为Mb值,表示内存占用的最高上限

5检测时间标准

共有两种方式:

1、ByProcess,以进程时间计算(默认)

2、ByNowTime,以启动当前时间计算

6回收动作

共有两种方式:

1、Kill,直接关闭释放进程(默认)

2、Command,执行命令行操作

7相关动作命令当第6项回收动作为Command时,此项为必输入项,表示要执行的 WINDOWS 命令行操作
8重新启用命令设置此项,则当关闭或执行动作命令后,尝试执行此命令
9计划强制关闭时间(小时)可以设定小时:分:秒(这个值前缀需要设置一个有效日期),代表每到此时此分此秒,则强制关闭进程

通过以上设置,我们可以灵活的对进程的关闭方式进行控制,以达到实际应用的目的。

其它设置

选择设置选项卡,如下图:

我们可设置窗口的透明度,另外可以设置两个选项:

1、只回收本程序启动时间以后的进程

2、只回收非激活窗口的进程, 指非操作系统显式的应用进程。

3、管理密码:默认值为111111,用于关闭应用程序等操作。

移动存储设备管理

这个选项如下图:

这是为移动设备存储数据库准备的一个选项,点击停止服务可以有效的、安全的移除存储设备,也可以继续启动服务。这个选项较少使用,也需要谨慎使用(因为它会尝试停止IIS、MS SQL SERVER 数据库服务等)。

核心代码-计时器监控

		private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e){DateTime cur_now=System.DateTime.Now;int cur_hour=cur_now.Hour;int cur_min=cur_now.Minute;int cur_sec=cur_now.Second;pc.CategoryName="Processor";pc.CounterName="% Processor Time";pc.InstanceName="_Total";//			pc.MachineName="michaeljane";float pcv=pc.NextValue();label7.Text="CPU利用率:"+(pcv).ToString()+" %";cpubar.Value=(int)(pcv);pcmem.CategoryName="Memory";pcmem.CounterName="Available MBytes";pcmem.InstanceName=null;//			richTextBox1.Text=pcpu.NextValue().ToString()+"\r\n";/*			System.Diagnostics.PerformanceCounter[] mypc; System.Diagnostics.PerformanceCounterCategory mycat = new System.Diagnostics.PerformanceCounterCategory("process");// Remove the current contents of the list.// Retrieve the counters.mypc = mycat.GetCounters();// Add the retrieved counters to the list.richTextBox1.Text="";for (int i = 0; i < mypc.Length; i++) { richTextBox1.Text+=(mypc[i].CounterName)+"\r\n";}
*///			float cpuLoad = pc.NextValue();try{label7.Text += "\r\n可用内存:" + pcmem.NextValue().ToString() + "M";}catch (Exception s){}statusBar1.Text=cur_now.ToString();  //显示当前时间Process[] processes; //定义进程组processes = System.Diagnostics.Process.GetProcesses(); //获得当前进程组Process process;  //定义初始进程中间变量string _pname,_killstate="";   //定义进程名变量,及进程回收状态字符串bool _kill=false;  //是否要回收标志变量bool _phandle=checkBox2.Checked;int _gcSpan;  //时间差变量DateTime _pdatetime,_checktime,_stdtime; //进程启动的时间变量和检测时间变量string[] _rv;    //接受检测结果的数组System.TimeSpan _dd; //时间差的秒数变量
//			string[] _processid=new string[1000];
//			DateTime[] _processLastTime=new DateTime[1000];
//			int[] _processLastMem=new int[1000];for(int i = 0;i<processes.Length-1;i++){process= processes[i];  //获得当前进程_pname=process.ProcessName.ToLower();  //获得进程名并转为小写try{_pdatetime = process.StartTime;  //获得进程的启动时间}catch(Exception e1){continue;}//				_rv=GetSubValueIndex(listBox1,_pname,"|");  //得到要回收的用户指定进程for(int li=0;li<listBox1.Items.Count;li++){_rv=listBox1.Items[li].ToString().Split('|');string ref_process=_rv[0].ToLower().Trim();int ref_span=int.Parse(_rv[1].ToString());string ref_cl=_rv[2].ToLower().Trim();float ref_rank=float.Parse(_rv[3].ToString());string ref_stdtime=_rv[4].ToLower().Trim();string ref_act=_rv[5].ToLower().Trim();string[] ref_cmd1=_rv[6].Split('↙');string[] ref_cmd2=_rv[7].Split('↙');string ref_closetime=_rv[8].Trim();//				richTextBox1.Text+=_rv[0]+_rv[1]+"\r\n";if(ref_process==_pname)  //如果是要回收的进程则进行处理{//如果在检测数组没有找到,则添加到检测数中int _curpoint=System.Array.IndexOf(_processid,process.Id);if(_curpoint<0){_stdtime=process.StartTime;if(ref_stdtime=="bynowtime"){_stdtime=System.DateTime.Now;}System.Diagnostics.PerformanceCounter pcm=new System.Diagnostics.PerformanceCounter("Process","% Processor Time",_pname);try{AddArray(process.Id, _stdtime, process.WorkingSet, pcm);}catch(Exception e3){}continue;}//						richTextBox1.Text+=((System.Diagnostics.PerformanceCounter)_processLastCPU[_curpoint]).NextValue().ToString()+"\r\n";try{float cur_rank = ((System.Diagnostics.PerformanceCounter)_processLastCPU[_curpoint]).NextValue();_checktime = System.DateTime.Now;  //检测时间为当前时间//开始分析CPU策略if (ref_cl == "cpu"){//如果当前进程的CPU占用率没有超过指定的上限,则重置最后的检测时间为当前时间,继续监测。if (cur_rank < ref_rank){_processLastTime[_curpoint] = _checktime;}}}catch(Exception e2){continue;}//开始分析memory策略if(ref_cl=="memory"){float _curmem=process.WorkingSet/(1024*1024);//							richTextBox1.Text+=_pname+" "+_curmem.ToString()+"\r\n";//如果当前进程的内存占用没有超过指定的上限,则重置最后的检测时间为当前时间,继续监测。if(_curmem<ref_rank){_processLastTime[_curpoint]=_checktime;}}_gcSpan=ref_span;  //得到用户指定的回收时间差_kill=false;_pdatetime=_processLastTime[_curpoint]; //得到进程的数组最后指定时间_dd=_checktime-_pdatetime;     //时间差以检测时间 减去 进行启动时间//如果时间差大于回收指定时间则可以回收进程,KILL变量为真if(checkBox1.Checked){//只回收本程序启动以后的进程时间if((_dd.TotalSeconds>_gcSpan)&&(_starttime<_pdatetime)){_kill=true;}}else{if(_dd.TotalSeconds>_gcSpan){_kill=true;}}//如果初期标识为可以关闭该进程,并且策略为强制性关闭,则进行内存判断if((_kill)&&(ref_cl=="force")){//如果内存有变化,则表示进程仍在活动,则不进行关闭,并更新检测内容int _curmem=process.WorkingSet;label6.Text=_curmem.ToString()+"  "+_processLastMem[_curpoint];if(_curmem!=_processLastMem[_curpoint]){_processLastTime[_curpoint]=_checktime;_processLastMem[_curpoint]=_curmem;_kill=false;}}//如果指定了强制关闭时间,则进行判断string close_tip="";if(ref_closetime!=""){DateTime ref_cls=DateTime.Parse(ref_closetime);if((ref_cls.Hour==cur_hour)&&(ref_cls.Minute==cur_min)&&(ref_cls.Second==cur_sec)){_kill=true;close_tip="强制关闭计划启动,计划时间为:"+ref_closetime;}}//如果只回收死进程,而当前进程为激活的窗口的话,则不关闭if((_phandle)&&((int)process.MainWindowHandle!=0)){_kill=false;}//如果可以回收则在文本框中添加回收状态,并将进程关闭if(_kill){if(!process.HasExited){if(ref_act=="kill"){//								MessageBox.Show("has exited");_killstate=close_tip+".进程"+_pname+"已被回收,关闭策略为"+ref_cl+",动作为:"+ref_act+"。进程的启动时间为"+_pdatetime.ToString()+",检测时间为:"+_checktime.ToString()+",现已经超时"+(_dd.TotalSeconds-_gcSpan).ToString()+"秒,回收时间单位是"+_gcSpan.ToString()+"秒。"+"进程ID:"+process.Id.ToString()+"进程主窗口句柄:"+process.MainWindowHandle.ToString();process.Kill();richTextBox1.AppendText(_killstate+"\r\n");}if(ref_act=="command"){//								MessageBox.Show("has exited");string _return="";for(int st=0;st<ref_cmd1.GetLength(0);st++){_return+=ref_cmd1[st]+" Result:"+WinExec(ref_cmd1[st],0).ToString()+"↙";}_killstate=close_tip+".进程"+_pname+"已被回收,关闭策略为"+ref_cl+",动作为:"+ref_act+",执行了命令:"+ref_cmd1+"。返回值为:"+_return+"。进程的启动时间为"+_pdatetime.ToString()+",检测时间为:"+_checktime.ToString()+",现已经超时"+(_dd.TotalSeconds-_gcSpan).ToString()+"秒,回收时间单位是"+_gcSpan.ToString()+"秒。"+"进程ID:"+process.Id.ToString()+"进程主窗口句柄:"+process.MainWindowHandle.ToString();richTextBox1.AppendText(_killstate+"\r\n");//										process.Kill();}//清空当前进程检测数组元素_processid[_curpoint]=0;_processLastTime[_curpoint]=_checktime;_processLastMem[_curpoint]=0;_processLastCPU[_curpoint]=null;}//判断进程是否已经退出}}//if proecesselse //如果没有找到进程名称,则二次判断任务是否提供了启动命令,如果提供,则运行它{}//end find process name}//li}//forprocesses = System.Diagnostics.Process.GetProcesses(); //获得当前进程组for(int ali=0;ali<listBox1.Items.Count;ali++){_rv=listBox1.Items[ali].ToString().Split('|');string ref_process=_rv[0].ToLower().Trim();int ref_span=int.Parse(_rv[1].ToString());string ref_cl=_rv[2].ToLower().Trim();float ref_rank=float.Parse(_rv[3].ToString());string ref_stdtime=_rv[4].ToLower().Trim();string ref_act=_rv[5].ToLower().Trim();string[] ref_cmd1=_rv[6].Split('↙');string ref_start_cmd=_rv[7];string[] ref_cmd2=_rv[7].Split('↙');bool _find=false;if(ref_start_cmd!=""){for(int i = 0;i<processes.Length-1;i++){process= processes[i];  //获得当前进程string cur_pname=process.ProcessName.ToLower();  //获得进程名并转为小写if(cur_pname==ref_process){_find=true;}}if(!_find){string _return="";for(int st=0;st<ref_cmd2.GetLength(0);st++){_return+=ref_cmd2[st]+" Result:"+WinExec(ref_cmd2[st],0).ToString()+"↙";}_killstate="进程"+ref_process+"尝试启动,关闭策略为"+ref_cl+",动作为:"+ref_act+",启动命令为:"+ref_cmd2+"。返回值为:"+_return+"。";richTextBox1.AppendText(_killstate+"\r\n");}}}//end for listbox}

小结

开发这款小工具,也是初识 System.Diagnostics(与系统进程、事件日志和性能计数器进行交互的类)的一个过程。

这里可以下载完整源码:https://download.csdn.net/download/michaelline/89140846

工具仅作学习使用,大家感兴趣的话可以按照自己的需求进行修改,感谢您的阅读,希望本文能对您有所帮助。

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

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

相关文章

内网渗透-Windows内网渗透

内网渗透-Windows内网渗透 文章目录 内网渗透-Windows内网渗透前言一、信息收集 1.1、SPN1.2、端口连接1.3、配置文件1.4、用户信息1.6、会话收集1.7、凭据收集 navicat&#xff1a;SecureCRT&#xff1a;Xshell&#xff1a;WinSCP&#xff1a;VNC: 1.8、DPAPI1.9、域信任1.10、…

视频编辑软件pitivi基本功之安装篇

视频编辑软件pitivi基本功之安装篇 台式机的系统是openSUSE-Leap-15.5-DVD-x86_64 应用程序——工具——终端&#xff0c;切换到root用户 ruhonglocalhost:~> su - 密码&#xff1a; localhost:~ # zypper search pitivi localhost:~ # zypper install pitivi ruhonglocalho…

PINet车道线检测+YOLOv8视频目标检测

前言&#xff1a; 本文主要目的是实现在PINet车道线检测的代码中嵌入YOLOv8的目标检测模块&#xff0c;具体效果如图所示&#xff1a; 在学习和使用YOLOv8进行目标检测时&#xff0c;感觉可以和最近研究的车道线检测项目结合起来&#xff0c;形成一套如上图所示的视频效…

c++的学习之路:4、入门(3)

摘要 本章将介绍一下auto、for和指针空值&#xff0c;文章末附上入门的所有代码。 目录 摘要 一、auto 二、for 三、指针空值 四、代码 五、思维导图 一、auto 这个关键字是c提出的&#xff0c;可以自动识别变量的类型&#xff0c;可以看出下方图片&#xff0c;auto自…

亚马逊、沃尔玛自养号测评技术解析:如何降低潜在风险

亚马逊等电商平台在全球范围内迅速扩张&#xff0c;竞争愈发激烈。为提升产品排名和销量&#xff0c;众多卖家选择采用自养号测评的策略。然而&#xff0c;自养号测评技术并非完美无缺&#xff0c;它存在着一定的技术局限性。由于缺乏对自养号原理及底层环境搭建的深入理解&…

三个截然不同的爆仓案例,值得每个交易者反思

用铜做镜子&#xff0c;能端正衣冠&#xff1b;以史为镜可知兴&#xff1b;以人为镜能明得与失得。”做买卖&#xff0c;需要以他人的得失为鉴&#xff0c;这样才会不断地反思持续地提高持续地进步。在这篇文章中&#xff0c;我们会分享3个完全不同的爆仓案例给交易者一个“与明…

ELK-Kibana 部署

目录 一、在 node1 节点上操作 1.1.安装 Kibana 1.2.设置 Kibana 的主配置文件 1.3.启动 Kibana 服务 1.4.验证 Kibana 1.5.将 Apache 服务器的日志&#xff08;访问的、错误的&#xff09;添加到 ES 并通过 Kibana 显示 1.6. 浏览器访问 二、部署FilebeatELK&…

密码学 | 椭圆曲线 ECC 密码学入门(三)

目录 7 这一切意味着什么&#xff1f; 8 椭圆曲线密码学的应用 9 椭圆曲线密码学的缺点 10 展望未来 ⚠️ 原文地址&#xff1a;A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留…

特氟龙(PFA)实验室器具有哪些?

PFA 是被称为塑料王&#xff0c;具有出众的化学耐受性&#xff0c;并且可在出色的温度范围内执行工作。 PFA 呈半透明&#xff0c;柔韧&#xff0c;并且由于其高密度重量有点重。PFA 具有惰性和低粘合性&#xff0c;溶出物和痕量金属含量较低。它具有较宽的含氟聚合物温度范围…

【gdb调试】在ubuntu环境使用gdb调试一棵四层二叉树的数据结构详解

目录 &#x1f31e;1. 整体思路 &#x1f31e;2. 准备内容 &#x1f33c;2.1 配置.c文件 &#x1f33c;2.2 准备测试程序 &#x1f33c;2.3 GDB调试基础 &#x1f31e;3. GDB调试四层二叉树 &#x1f33c;3.1 测试程序分析 &#x1f33c;3.2 gdb分析 &#x1f33b;1. …

这些矛盾点不搞清楚,私域怎么做得起来!

最近不少人都在问&#xff0c;私域做不起来怎么办&#xff1f;有很多企业砸了不少钱&#xff0c;有些还做了好几年&#xff0c;依旧没有起色。 有些企业觉得私域做不起来的阻碍有运营方面的原因&#xff0c;比如文案写不好&#xff0c;社群不知道怎么管理&#xff1b;有团队方…

Apache Zeppelin 命令执行漏洞复现(CVE-2024-31861)

0x01 产品简介 Apache Zeppelin 是一个让交互式数据分析变得可行的基于网页的开源框架&#xff0c;Zeppelin提供了数据分析、数据可视化等功能&#xff0c; 0x02 漏洞概述 Apache Zeppelin 中代码生成控制不当&#xff08;“代码注入”&#xff09;漏洞。攻击者可以使用 She…

Vitis HLS 学习笔记--硬件卷积加速 Filter2DKernel

目录 加速器功能 Window2D()函数 实现代码 变量解释 ARRAY_PARTITION DEPENDENCE LOOP_TRIPCOUNT ramp_up 更新Window 更新LineBuffer Filter2D()函数 ARRAY_PARTITION window_stream.read() 计算过程 备注 加速器功能 硬件加速单元从全局内存&#xff08;DDR&a…

Centos7配置IP地址

1、找到网卡名字 使用root用户登陆&#xff0c;输入命令 ifconfig 2、打开配置文件 输入命令&#xff0c;打开配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33 3、添加IP地址 3.1修改BOOTPROTO 将“BOOTPROTOdhcp” 改为 “BOOTPROTOstatic” 3.2添加IP地址 在配…

D365开发-在视图按钮的js里,引用别的js里的公共方法

公共方法写法&#xff1a; "use strict"; var JJMC window.JJMC || {}; JJMC.SamMCommon JJMC.SamMCommon || {}; (function () { this.cloneRecord function (excludeAttrbuteNames){ / } }).call(JJMC.SamMCommon); 然后在需要调方法的command里面&#xff0c;之…

解读《算者生存:商业分析的方法与实践》:构建企业经营分析框架的必备指南

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

Java:定时任务无法正常执行(scheduling + ShedLock)

目录 一、场景二、代码片段三、排查四、原因五、解决 一、场景 1、使用定时任务(scheduling) 分布式锁(ShedLock)定期执行一段代码 2、configureTasks()对于任务执行周期的更新是正常的 3、但任务方法无法被执行 二、代码片段 三、排查 1、确认Trigger没有问题 2、查看red…

水封式防暴器 我的真诚一直不变

天气在变&#xff0c;服务不变&#xff0c;季节在变&#xff0c;态度不变&#xff0c;时代在变&#xff0c;品质不变&#xff0c;不管世界怎么变&#xff0c;我的真诚一直不变&#xff01; 一、水封式防暴器的用途介绍&#xff1a; FBQ型系列水封式防暴器是安装在抽放瓦斯泵吸…

如何在没有备份的情况下恢复iPhone数据

想要找到没有备份的最佳iPhone数据恢复软件吗&#xff1f;本文介绍了一款专业的iPhone数据恢复软件&#xff0c;无需备份即可恢复iPhone数据。 许多iPhone用户可能对上述情况并不陌生。丢失重要的iPhone数据确实是一件令人沮丧的事情。通常&#xff0c;检索iPhone数据的最佳方…

第九届少儿模特明星盛典 全球赛首席体验官『魏堃明』精彩回顾

2024年1月30日-2月1日&#xff0c;魔都上海迎来了龙年第一场“少儿形体行业美育春晚”&#xff01;由IPA模特委员会主办的第九届少儿模特明星盛典全球总决赛圆满收官&#xff01;近2000名少儿模特选手从五湖四海而来&#xff0c;决战寒假这场高水准&#xff0c;高人气&#xff…