我正在编写一个程序,必须记录启动记事本等过程的时间.我认为创建一个每秒检查所有进程的Timer是很好的.但我认为它会减慢用户的计算机速度.有没有更好的方法呢?
最初确定所有正在运行的进程的创建时间。然后使用 WMI 注册进程创建事件。
请参阅下面的代码,了解如何使用 WMI 处理进程创建事件的小示例:
static void Main(string[] args)
{
using (ManagementEventWatcher eventWatcher =
new ManagementEventWatcher(@"SELECT * FROM
__InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"))
{
// Subscribe for process creation notification.
eventWatcher.EventArrived += ProcessStarted_EventArrived;
eventWatcher.Start();
Console.In.ReadLine();
eventWatcher.EventArrived -= ProcessStarted_EventArrived;
eventWatcher.Stop();
}
}
static void ProcessStarted_EventArrived(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject obj = e.NewEvent["TargetInstance"] as ManagementBaseObject;
// The Win32_Process class also contains a CreationDate property.
Console.Out.WriteLine("ProcessName: {0} " + obj.Properties["Name"].Value);
}
Run Code Online (Sandbox Code Playgroud)
开始编辑:
我进一步研究了 WMI 的进程创建检测,并且有一个使用该类的(更多)资源友好的解决方案(但需要管理权限)Win32_ProcessStartTrace(请参阅TECHNET以获取更多信息):
using (ManagementEventWatcher eventWatcher =
new ManagementEventWatcher(@"SELECT * FROM Win32_ProcessStartTrace"))
{
// Subscribe for process creation notification.
eventWatcher.EventArrived += ProcessStarted_EventArrived;
eventWatcher.Start();
Console.Out.WriteLine("started");
Console.In.ReadLine();
eventWatcher.EventArrived -= ProcessStarted_EventArrived;
eventWatcher.Stop();
}
static void ProcessStarted_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.Out.WriteLine("ProcessName: {0} "
+ e.NewEvent.Properties["ProcessName"].Value);
}
Run Code Online (Sandbox Code Playgroud)
在此解决方案中,您不必设置轮询间隔。
结束编辑
开始编辑 2:
您可以使用该类Win32_ProcessStopTrace来监视进程停止事件。要组合进程启动和进程停止事件,请使用该类Win32_ProcessTrace。在事件处理程序中使用ClassPath探针来区分启动/停止事件:
using (ManagementEventWatcher eventWatcher =
new ManagementEventWatcher(@"SELECT * FROM Win32_ProcessTrace"))
{
eventWatcher.EventArrived += Process_EventArrived;
eventWatcher.Start();
Console.Out.WriteLine("started");
Console.In.ReadLine();
eventWatcher.EventArrived -= Process_EventArrived;
eventWatcher.Stop();
}
static void Process_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.Out.WriteLine(e.NewEvent.ClassPath); // Use class path to distinguish
// between start/stop process events.
Console.Out.WriteLine("ProcessName: {0} "
+ e.NewEvent.Properties["ProcessName"].Value);
}
Run Code Online (Sandbox Code Playgroud)
结束编辑2