2009-05-11 58 views
20

Có cách nào để đăng ký sự kiện kích hoạt khi tệp thực thi của một tên tệp cụ thể bắt đầu không? Tôi biết thật dễ dàng để có được một sự kiện khi một quá trình thoát, bằng cách xử lý quy trình và đăng ký sự kiện đã thoát. Nhưng làm thế nào bạn có thể được thông báo khi một quá trình, mà không phải là đã chạy, bắt đầu ... mà không bỏ phiếu tất cả các tiến trình đang chạy?Sự kiện .NET cho quá trình thực thi Quy trình

Trả lời

30

Bạn có thể sử dụng như sau:

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)); 
    } 

Sau đó bạn sẽ gọi một trong hai WatchForProcessStart và/hoặc WatchForProcessEnd đi qua trong quá trình tên của bạn (ví dụ: "notepad.exe").

Đối tượng ManagementEventWatcher được trả về từ hai phương thức Watch * khi nó triển khai IDisposable và vì vậy bạn nên gọi Dispose trên các đối tượng này khi bạn đã kết thúc với chúng để ngăn sự cố.

Bạn cũng có thể thay đổi giá trị bỏ phiếu trong các truy vấn nếu bạn cần sự kiện được tăng lên nhanh hơn sau khi quá trình đã bắt đầu. Để thực hiện việc này, hãy thay đổi dòng "WITHIN 10" thành WITHIN ít hơn 10.

+0

Mã này có thể được cấu trúc lại, nhưng tôi đã để nó tiết lộ để hy vọng có thể hiểu được – Clive

+1

Bây giờ đó là câu trả lời! Cảm ơn! –

+0

thực sự mã này có vẻ tốt. Nhưng nó không có tác dụng với tôi. Tôi đang thiếu bất kỳ điểm nào? win7, net 2.o dự án. – Yaya

3

WMI có thể tạo sự kiện khi quy trình được tạo. Sau đó, bạn có thể lọc các sự kiện này.

+1

Ví dụ sẽ đẹp :) –

+0

@Adam: Tôi đã mong nhận xét đó. Thật không may, nó đã được một thời gian kể từ khi tôi làm việc với WMI sự kiện (năm), và không phải với NET vì vậy tôi sẽ phải tìm hiểu làm thế nào để làm điều đó bản thân mình ... và không có thời gian tại thời điểm này. – Richard

1

Đây là mã.

Lưu ý rằng bạn phải khởi động Visual Studio giống như Quản trị viên để thực thi mã này.

using System; 
using System.Management; 

namespace AppLaunchDetector 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     {   
      ManagementEventWatcher w = null; 
      WqlEventQuery q; 
      try 
      { 
       q = new WqlEventQuery(); 
       q.EventClassName = "Win32_ProcessStartTrace"; 
       w = new ManagementEventWatcher(q); 
       w.EventArrived += new EventArrivedEventHandler(ProcessStartEventArrived); 
       w.Start(); 
       Console.ReadLine(); // block main thread for test purposes 
      } 
      catch (Exception ex) 
      { 

      } 
      finally 
      { 
       w.Stop(); 
      } 
     } 

     static void ProcessStartEventArrived(object sender, EventArrivedEventArgs e) 
     { 
      foreach (PropertyData pd in e.NewEvent.Properties) 
      { 
       Console.WriteLine("\n============================= ========="); 
       Console.WriteLine("{0},{1},{2}", pd.Name, pd.Type, pd.Value); 
      } 
     } 
    } 
} 
Các vấn đề liên quan