2012-01-15 21 views
6

Tôi đang viết chương trình phải đăng ký thời gian bắt đầu quá trình như notepad. Tôi nghĩ rằng nó là tốt để tạo ra một bộ đếm thời gian kiểm tra tất cả các quá trình mỗi giây. Nhưng tôi nghĩ rằng nó sẽ làm chậm máy tính của người dùng. Có cách nào tốt hơn để làm điều này?Cách tốt nhất để đăng ký thời gian bắt đầu quá trình?

+1

Có, việc bỏ phiếu liên tục là giải pháp sai vì nhiều lý do, không phải ít nhất là giải pháp giảm hiệu suất. Bạn đang tìm kiếm một cái móc. Nhưng bạn không thể viết DLL hook trong C#; bạn sẽ cần phải sử dụng C hoặc C++ cho điều đó. –

+0

Mục tiêu thực tế của bạn là gì? Rất khó cho bạn câu trả lời giải quyết vấn đề của bạn. Bạn có muốn theo dõi bất kỳ quá trình bắt đầu hoặc chỉ bắt đầu một quá trình cụ thể? Bạn có cần phải có được thời gian chạy của các quy trình được giám sát một cách chính xác hay chỉ là bạn quan tâm đến các quy trình chạy lâu hơn, ví dụ: 10 phút? Tùy thuộc vào câu trả lời của bạn nó có thể bật ra rằng bỏ phiếu là một sự cân bằng "đủ tốt". Có những cách chính xác để làm điều đó nhưng chúng phức tạp hơn nhiều. –

+0

Xin lỗi, ** Tiếng Anh rất khó đối với tôi **. Tôi muốn đo thời gian chạy một quá trình và đăng ký nó trong một tập tin txt. Nhưng tôi không muốn kiểm tra nó mỗi giây. –

Trả lời

3

Xác định ban đầu cho tất cả các quy trình đang chạy trong thời gian tạo. Sau đó, sử dụng WMI để đăng ký các sự kiện tạo quy trình.

Xem mã dưới đây cho một ví dụ nhỏ về cách sử dụng WMI cho các sự kiện tạo ra quá trình:

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

BEGIN EDIT:

Tôi đã điều tra tiếp tục phát hiện sự sáng tạo quá trình với WMI và có là một giải pháp thân thiện (nhiều hơn) resouces (nhưng cần đặc quyền quản trị) sử dụng lớp Win32_ProcessStartTrace (vui lòng xem TECHNET để biết thêm thông tin):

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

Trong giải pháp này, bạn không phải đặt khoảng thời gian bỏ phiếu.

END EDIT

BEGIN EDIT 2:

Bạn có thể sử dụng lớp Win32_ProcessStopTrace để theo dõi các sự kiện quá trình dừng lại. Để kết hợp cả quá trình bắt đầu quá trình và bắt đầu quá trình, hãy sử dụng lớp Win32_ProcessTrace. Trong xử lý sự kiện sử dụng ClassPath proberty để phân biệt giữa khởi động/dừng sự kiện:

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

END EDIT 2

+0

-1 WMI đầu tiên thực hiện bên trong. Thứ hai, bạn không cần phải sử dụng WMI. Hệ điều hành ghi lại thời gian bắt đầu của mọi quá trình. Tất cả những gì bạn cần làm là đọc nó. Xem câu trả lời của tôi dưới đây. –

+0

Cảm ơn. Có cách nào để kiểm tra quá trình đóng không? –

+1

@ MoctavaFarzán: Có, đó cũng là sự kiện __InstanceDeletionEvent. Nhưng nếu bạn dự định sử dụng cả __InstanceDeletionEvent và __InstanceCreationEvent, bạn nên đăng ký __InstanceOperationEvent và sau đó kiểm tra lại gọi lại sự kiện của bạn đã được kích hoạt bằng cách đánh giá thuộc tính e.NewEvent.ClassPath.ClassName. – Hans

2

Không cần phải theo dõi bất cứ điều gì cả. Tất cả những gì bạn cần làm là liệt kê các quy trình của bạn và tìm nạp từ các cá thể tiến trình StartTime.

+0

Nhưng bạn chắc chắn phải sử dụng một bộ đếm thời gian hoặc một cái gì đó như thế? Đếm các quá trình một lần là không đủ. Vì vậy, tôi không hiểu tại sao bạn lại bỏ phiếu cho câu trả lời của tôi? – Hans

+0

Có nhiều cách để đạt được nó mà không cần hẹn giờ. Vấn đề chính với câu trả lời của bạn là với "__InstanceCreationEvent WITHIN 1" bạn thực hiện bình chọn mỗi giây. Nếu một quá trình bắt đầu và dừng lại trong thời gian đó, bạn sẽ không bao giờ nhận được bất kỳ thông báo nào. Nếu bạn biết bạn muốn kiểm tra quy trình nào, bạn có thể nhận được cuộc gọi lại từ hệ điều hành khi bạn sử dụng Tùy chọn thực thi tệp hình ảnh. Nhưng Farzan đầu tiên nên nói rằng làm thế nào anh ta có được các quá trình trong câu hỏi và đó là thú vị cho anh ta. Có rất nhiều cách để đạt được điều này. –

+0

Vâng, tôi rất lo lắng. Có nhiều giải pháp như Tùy chọn thực thi tệp hình ảnh, Hooks, bỏ phiếu bằng bộ hẹn giờ, sử dụng WMI hoặc sử dụng trình điều khiển. Vì vậy, tôi thực sự không hiểu phiếu bầu của bạn. – Hans

Các vấn đề liên quan