一尘不染

进程可执行文件启动的.NET事件

c#

有什么方法可以注册当特定文件名的可执行文件启动时触发的事件?我知道通过获取进程句柄并注册退出的事件,很容易在进程退出时获取事件。但是如何在尚未轮询所有正在运行的进程的情况下启动未运行的进程的通知呢?


阅读 262

收藏
2020-05-19

共1个答案

一尘不染

您可以使用以下内容:

    private ManagementEventWatcher WatchForProcessStart(string processName)
    {
        string queryString =
            "SELECT TargetInstance" +
            "  FROM __InstanceCreationEvent " +
            "WITHIN  10 " +
            " WHERE TargetInstance ISA 'Win32_Process' " +
            "   AND TargetInstance.Name = '" + processName + "'";

        // The dot in the scope means use the current machine
        string scope = @"\\.\root\CIMV2";

        // Create a watcher and listen for events
        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
        watcher.EventArrived += ProcessStarted;
        watcher.Start();
        return watcher;
    }

    private ManagementEventWatcher WatchForProcessEnd(string processName)
    {
        string queryString =
            "SELECT TargetInstance" +
            "  FROM __InstanceDeletionEvent " +
            "WITHIN  10 " +
            " WHERE TargetInstance ISA 'Win32_Process' " +
            "   AND TargetInstance.Name = '" + processName + "'";

        // The dot in the scope means use the current machine
        string scope = @"\\.\root\CIMV2";

        // Create a watcher and listen for events
        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
        watcher.EventArrived += ProcessEnded;
        watcher.Start();
        return watcher;
    }

    private void ProcessEnded(object sender, EventArrivedEventArgs e)
    {
        ManagementBaseObject targetInstance = (ManagementBaseObject) e.NewEvent.Properties["TargetInstance"].Value;
        string processName = targetInstance.Properties["Name"].Value.ToString();
        Console.WriteLine(String.Format("{0} process ended", processName));
    }

    private void ProcessStarted(object sender, EventArrivedEventArgs e)
    {
        ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
        string processName = targetInstance.Properties["Name"].Value.ToString();
        Console.WriteLine(String.Format("{0} process started", processName));
    }

然后,您可以传入进程名称(例如“ notepad.exe”)来调用WatchForProcessStart和/或WatchForProcessEnd。

ManagementEventWatcher对象在实现IDisposable时从这两个Watch
*方法返回,因此在完成处理后,应该对这些对象调用Dispose,以防止出现问题。

如果您需要在过程开始后更快地引发事件,则还可以在查询中更改轮询值。为此,将“ WITHIN 10”行更改为小于10的值。

2020-05-19