我有这段代码来检测进程:
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");
}
答案 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事件以确切知道进程何时死亡。