作用域和静态函数的 C# 问题
C# problem with Scopes and static Functions
我正在编写一个程序,它将 expand/minimize 取决于另一个进程(游戏客户端)是否为 opened/terminated。
它将成为一个登录助手,在 windows 表单上显示帐户。
为了监控进程是否打开,我使用 C# 的 WMI。
这是我检查客户端状态的代码:
public static int Main(string[] args)
{
// query for filtering which process is montitored.
string pol = "2";
string queryString =
"SELECT *" +
" FROM __InstanceOperationEvent " +
"WITHIN " + pol +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = 'RiotClientCrashHandler.exe'"; // look for that process every 2 seconds.
string scope = @"\.\root\CIMV2";
ManagementEventWatcher startWatch = new ManagementEventWatcher(scope, queryString);
startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived); // event handler
startWatch.Start();
ManagementEventWatcher stopWatch = new ManagementEventWatcher(scope, queryString);
stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived); // event handler for terminating
stopWatch.Start();
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(50); // wait loop.
startWatch.Stop();
stopWatch.Stop();
return 0;
}
static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("Process Stopped! Riot Client");
}
static void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("Process opened! Riot Client");
}
非常基本的程序。事件的两个回调函数,即进程是started/terminated.
问题
客户端似乎没有一次调用这两个事件,而是每秒重新启动一次进程。
几秒钟后它重复调用:
我想用定时器实现一个定时器class:
Timer timer = new Timer();
timer.Elapsed += new ElapsedEventHandler(ClosingEvent);
timer.Interval = 3000;
timer.Start();
它应该等待一个设定的时间,在关闭事件被调用后(意味着进程必须完全终止)。
如果打开的事件被调用则重置。
我是从 C/Python/Javascript 开始接触 C# 的新手,所以不要对我有恶意。似乎我不能在这里声明一个全局变量,所以我有点困惑如何解决这个问题。我也不能从静态函数中调用非静态函数。
有办法解决吗?
- 我应该用计时器解决这个问题吗?
- 是否有使用 WMI 的不同方法?
一些事情。使用 __InstanceOperationEvent class 将为您提供命名空间的所有创建、删除和修改事件。这意味着任何时候流程实例上的任何 属性 发生变化,例如内存(经常发生),您都会收到一个要处理的事件。这就是为什么你会收到这么多事件。
我注意到的另一件事是您的 startWatch 和 stopWatch 代码共享同一个查询。这意味着您无论如何都会收到重复的事件,即使 WMI 事件只是在创建和删除时引发。您可以将它们组合到一个对象和事件处理程序中,然后处理您的代码中正在处理的事件类型,如下所示。
public static int Main(string[] args)
{
// query for filtering which process is montitored.
string pol = "2";
string queryString =
"SELECT *" +
" FROM __InstanceOperationEvent " +
"WITHIN " + pol +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = 'RiotClientCrashHandler.exe'"; // look for that process every 2 seconds.
string scope = @"\.\root\CIMV2";
ManagementEventWatcher processWatcher = new ManagementEventWatcher(scope, queryString);
processWatcher.EventArrived += new EventArrivedEventHandler(ProcessEventArrived); // event handler
processWatcher.Start();
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(50); // wait loop.
processWatcher.Stop();
return 0;
}
static void ProcessEventArrived(object sender, EventArrivedEventArgs e)
{
// Check the event arguments to see if the event being raised is creation or deletion
switch (e.NewEvent.ClassPath.ClassName)
{
case "__InstanceCreationEvent":
Console.WriteLine("Process opened! Riot Client");
break;
case "__InstanceDeletionEvent":
Console.WriteLine("Process Stopped! Riot Client");
break;
default:
break;
}
}
综上所述,如果可能,请尝试使用事件 class Win32_ProcessTrace
来提高性能。此 class 旨在仅处理进程启动和停止,因此它比查找 WMI 实例修改更精简。唯一的缺点是它需要更高的权限(管理员权限),这在您的环境中可能是不可能的。
我正在编写一个程序,它将 expand/minimize 取决于另一个进程(游戏客户端)是否为 opened/terminated。 它将成为一个登录助手,在 windows 表单上显示帐户。
为了监控进程是否打开,我使用 C# 的 WMI。 这是我检查客户端状态的代码:
public static int Main(string[] args)
{
// query for filtering which process is montitored.
string pol = "2";
string queryString =
"SELECT *" +
" FROM __InstanceOperationEvent " +
"WITHIN " + pol +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = 'RiotClientCrashHandler.exe'"; // look for that process every 2 seconds.
string scope = @"\.\root\CIMV2";
ManagementEventWatcher startWatch = new ManagementEventWatcher(scope, queryString);
startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived); // event handler
startWatch.Start();
ManagementEventWatcher stopWatch = new ManagementEventWatcher(scope, queryString);
stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived); // event handler for terminating
stopWatch.Start();
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(50); // wait loop.
startWatch.Stop();
stopWatch.Stop();
return 0;
}
static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("Process Stopped! Riot Client");
}
static void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("Process opened! Riot Client");
}
非常基本的程序。事件的两个回调函数,即进程是started/terminated.
问题
客户端似乎没有一次调用这两个事件,而是每秒重新启动一次进程。
几秒钟后它重复调用:
我想用定时器实现一个定时器class:
Timer timer = new Timer();
timer.Elapsed += new ElapsedEventHandler(ClosingEvent);
timer.Interval = 3000;
timer.Start();
它应该等待一个设定的时间,在关闭事件被调用后(意味着进程必须完全终止)。 如果打开的事件被调用则重置。
我是从 C/Python/Javascript 开始接触 C# 的新手,所以不要对我有恶意。似乎我不能在这里声明一个全局变量,所以我有点困惑如何解决这个问题。我也不能从静态函数中调用非静态函数。 有办法解决吗?
- 我应该用计时器解决这个问题吗?
- 是否有使用 WMI 的不同方法?
一些事情。使用 __InstanceOperationEvent class 将为您提供命名空间的所有创建、删除和修改事件。这意味着任何时候流程实例上的任何 属性 发生变化,例如内存(经常发生),您都会收到一个要处理的事件。这就是为什么你会收到这么多事件。
我注意到的另一件事是您的 startWatch 和 stopWatch 代码共享同一个查询。这意味着您无论如何都会收到重复的事件,即使 WMI 事件只是在创建和删除时引发。您可以将它们组合到一个对象和事件处理程序中,然后处理您的代码中正在处理的事件类型,如下所示。
public static int Main(string[] args)
{
// query for filtering which process is montitored.
string pol = "2";
string queryString =
"SELECT *" +
" FROM __InstanceOperationEvent " +
"WITHIN " + pol +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = 'RiotClientCrashHandler.exe'"; // look for that process every 2 seconds.
string scope = @"\.\root\CIMV2";
ManagementEventWatcher processWatcher = new ManagementEventWatcher(scope, queryString);
processWatcher.EventArrived += new EventArrivedEventHandler(ProcessEventArrived); // event handler
processWatcher.Start();
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(50); // wait loop.
processWatcher.Stop();
return 0;
}
static void ProcessEventArrived(object sender, EventArrivedEventArgs e)
{
// Check the event arguments to see if the event being raised is creation or deletion
switch (e.NewEvent.ClassPath.ClassName)
{
case "__InstanceCreationEvent":
Console.WriteLine("Process opened! Riot Client");
break;
case "__InstanceDeletionEvent":
Console.WriteLine("Process Stopped! Riot Client");
break;
default:
break;
}
}
综上所述,如果可能,请尝试使用事件 class Win32_ProcessTrace
来提高性能。此 class 旨在仅处理进程启动和停止,因此它比查找 WMI 实例修改更精简。唯一的缺点是它需要更高的权限(管理员权限),这在您的环境中可能是不可能的。