快速过程检测

时间:2014-07-11 00:56:41

标签: c# process detection

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

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

由于代码必须运行很多次,因为它在Timer中,有没有办法提高进程的速度? 我对比赛没有任何控制权。

此代码位于始终启用的计时器内,间隔为2000-3000 ms:

if (IsGameRunning())
            {
                Do stuff
            }
            else
            {

                Status("Waiting for game to start");
            }

2 个答案:

答案 0 :(得分:1)

鉴于该进程是由另一个进程启动的,在这种情况下是Steam,我们可以缩小列表以仅搜索子进程。

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

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

然后使用Windows Management Instrumentation(使用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);
    }
}

e.g。 IsGameRunning(parentProcess.Id, "SuperMeatBoy.exe")

无法保证这是更快,因为我还没有进行任何比较测试,但是根据以前使用WMI的经验比迭代一系列进程更有效。

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

答案 1 :(得分:0)

在查看任务管理器中运行时,WMI会为您带来明显的性能损失,同时出现明显的重复CPU峰值。我进行流程搜索工作的方法是在Process.GetProcessByName上使用linq语句,当我每隔0.3秒扫描一次进程时,我从未见过这个语句超过0%。我将已经知道的进程存储在内存中,并在linq语句中过滤掉它们。

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