快速进程检测

本文关键字:检测 进程 | 更新日期: 2023-09-27 18:12:20

我有这段代码来检测进程:

private Boolean IsGameRunning()
    {
        Process[] game = Process.GetProcesses();
        foreach (Process process in game)
        {
            if (process.ProcessName.Contains("GameWindow"))
            {
                return true;
            }
        }
        return false;
    }

由于代码必须运行很多次,因为它是在一个计时器内,有任何方法来提高进程的速度?我对比赛没有任何控制权。

这段代码位于一个始终启用的定时器内,间隔为2000-3000毫秒:

if (IsGameRunning())
            {
                Do stuff
            }
            else
            {
                Status("Waiting for game to start");
            }

快速进程检测

考虑到进程是由另一个进程启动的,在本例中是Steam,我们可以缩小列表以只搜索子进程。

首先,需要获得父进程id (PID)。

var parentProcess = Process.GetProcesses().FirstOrDefault(x => x.ProcessName == "Steam");

然后使用Windows管理工具(通过System.Management.dll访问),您可以只搜索子进程

bool IsGameRunning(int parentProcess, string childExecutableName)
{
    var query = string.Format("SELECT * FROM Win32_Process WHERE ParentProcessId = {0} AND Name = '{1}'", parentProcess, childExecutableName);
    using (var searcher = new ManagementObjectSearcher(query))
    using (var results = searcher.Get())
    {
        return (results.Count > 0);
    }
}

IsGameRunning(parentProcess.Id, "SuperMeatBoy.exe")

不能保证更快,因为我没有做过任何比较测试,但是从以前使用WMI的经验来看,它比迭代进程列表的性能更高。

如果你想更进一步,一个更高级的解决方案是连接事件来告诉你进程是使用ManagementEventWatcher创建和删除的,如这篇博客文章http://weblogs.asp.net/whaggard/438006所示。

WMI在任务管理器中运行时,会给您带来明显的性能影响,并且会出现明显的CPU峰值。我使进程搜索工作的方法是在process上使用linq语句。GetProcessByName,我从未见过它在每0.3秒扫描一次进程时超过0%。我将已经知道的进程存储在内存中,并在linq语句中将它们过滤掉。

如果您的EXE有足够的权限(或被提升),您可以设置EnableRaisingEvents = true,并附加到Exited事件以确切地知道进程何时死亡。