用于Process可执行文件的.NET事件

Ada*_*ile 19 .net c# events process

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

Cli*_*ive 30

您可以使用以下内容:

    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));
    }
Run Code Online (Sandbox Code Playgroud)

然后,您将调用WatchForProcessStart和/或WatchForProcessEnd传入您的进程名称(例如"notepad.exe").

ManagementEventWatcher对象是从两个Watch*方法返回的,因为它实现了IDisposable,所以你应该在完成这些对象后调用Dispose以防止出现问题.

如果您需要在进程启动后更快地引发事件,还可以更改查询中的轮询值.要执行此操作,请将"WITHIN 10"行更改为少于10的WITHIN.