如何通过外部程序检测并终止闲置5分钟以上的进程?
实现IdleReader.exe的闲置检测与进程终止逻辑
嘿,我来帮你完善IdleReader.exe里的闲置检测逻辑!要实现目标,我们需要从两个维度判断程序是否符合终止条件:一是系统层面的键鼠闲置时长,二是进程自身的活动状态。下面一步步来实现:
第一步:引入Windows API获取系统闲置时间
首先我们需要调用Windows的GetLastInputInfo API来获取用户最后一次操作键鼠的时间,这能帮我们判断系统是否处于闲置状态。在你的类里先添加这个API的声明:
[StructLayout(LayoutKind.Sequential)] private struct LASTINPUTINFO { public uint cbSize; public uint dwTime; } [DllImport("user32.dll")] private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); // 计算系统闲置时长的方法 private TimeSpan GetSystemIdleTime() { LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo); GetLastInputInfo(ref lastInputInfo); return TimeSpan.FromMilliseconds(Environment.TickCount - lastInputInfo.dwTime); }
第二步:检测进程的活动状态
接下来判断进程自身是否有活动,我们可以通过监测进程的CPU使用率来判断(如果进程长时间CPU使用率接近0,说明它可能处于闲置状态)。这里写一个简单的方法来获取进程的CPU使用情况:
private bool IsProcessActive(Process process) { try { // 获取进程的CPU使用率,取两次采样的平均值避免瞬时值误差 process.Refresh(); DateTime startTime = DateTime.Now; TimeSpan startCpuTime = process.TotalProcessorTime; // 等待100毫秒后再次采样 System.Threading.Thread.Sleep(100); process.Refresh(); DateTime endTime = DateTime.Now; TimeSpan endCpuTime = process.TotalProcessorTime; // 计算CPU使用率 double cpuUsage = (endCpuTime.TotalMilliseconds - startCpuTime.TotalMilliseconds) / (endTime - startTime).TotalMilliseconds / Environment.ProcessorCount * 100; // 如果CPU使用率低于1%,认为进程无活动 return cpuUsage > 1; } catch { // 进程可能已终止,默认视为非活动 return false; } }
第三步:整合逻辑到你的代码中
现在把闲置检测和进程终止的逻辑放到你原来的代码块里,替换掉注释的部分:
private void refresh_PrgList() { using (var con = new SqlConnection(ConfigurationManager.AppSettings["ConnectionStr"])) using (var cmd = con.CreateCommand()) { con.Open(); cmd.CommandText = "select ProgramID, ProgramName from MKTPrograms"; var reader = cmd.ExecuteReader(); var yy = false; dgvPrgList.Rows.Clear(); // 获取系统闲置时长 TimeSpan systemIdleTime = GetSystemIdleTime(); // 定义闲置阈值:5分钟 TimeSpan idleThreshold = TimeSpan.FromMinutes(5); while (reader.Read()) { yy = false; foreach (var xx in Process.GetProcesses()) { if (xx.ProcessName.Replace(".exe", string.Empty).ToUpper() == reader[0].ToString().Replace(" ", string.Empty).ToUpper()) { // 检测闲置状态:系统闲置超过5分钟 且 进程无活动 bool isSystemIdle = systemIdleTime >= idleThreshold; bool isProcessIdle = !IsProcessActive(xx); bool shouldTerminate = isSystemIdle && isProcessIdle; // 计算进程闲置时长(用系统闲置时长近似) TimeSpan processIdleTime = systemIdleTime; // 更新DataGridView显示状态 string status = "Running"; if (shouldTerminate) { status = "Idle (Terminated)"; try { // 终止进程 xx.Kill(); xx.WaitForExit(); } catch (Exception ex) { status = $"Idle (Terminate Failed: {ex.Message})"; } } else if (isProcessIdle) { status = $"Idle ({processIdleTime.Minutes} mins)"; } dgvPrgList.Rows.Add(new object[] { reader[0].ToString(), reader[1].ToString(), status, xx.StartTime, System.DateTime.Now - xx.StartTime }); yy = true; break; // 找到匹配进程后退出循环 } } if (!yy) { dgvPrgList.Rows.Add(new object[] { reader[0].ToString(), reader[1].ToString(), "Stopped", "", "" }); } } for (int x = 0 ; x < dgvPrgList.Columns.Count ; x++ ) { dgvPrgList.Columns[x].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; } } }
关键逻辑说明
- 系统闲置检测:通过
GetLastInputInfo获取用户最后操作时间,计算出系统闲置时长,和5分钟阈值对比。 - 进程活动检测:通过采样进程的CPU使用率,判断进程是否有实际运行的任务。
- 进程终止:当两个条件都满足(系统闲置超5分钟+进程无活动),调用
Kill()方法终止进程,并捕获异常避免出错。 - 界面显示:在DataGridView里展示进程的状态(运行中、闲置、已终止等),方便查看。
这样你的IdleReader.exe就能准确识别并终止符合条件的闲置进程啦,比如示例里的pgrC.exe和pgrE.exe都会被自动终止。
内容的提问来源于stack exchange,提问作者Arief Ilham
相关产品推荐
相关产品推荐

