我正在寫一個程序,必須註冊啓動一個進程的時間,如記事本。 我認爲可以創建一個每秒鐘檢查所有進程的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);
}
BEGIN編輯:
我進一步調查過程中創造的檢測與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);
}
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);
}
在此解決方案中,您不必設置輪詢間隔。
編輯完
BEGIN編輯2:
您可以使用Win32_ProcessStopTrace
類監測過程停止事件。要組合進程啓動和進程停止事件,請使用Win32_ProcessTrace
類。在事件處理程序使用ClassPath
proberty開始區分/停止事件:
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
-1第一個WMI在內部彙集。其次,你甚至不需要使用WMI。操作系統確實記錄了每個進程的開始時間。你所需要做的就是閱讀它。請參閱下面的答案。 – 2012-01-15 08:50:26
謝謝。有沒有辦法檢查關閉過程呢? – 2012-01-15 09:25:41
@MoctavaFarzán:是的,還有一個__InstanceDeletionEvent事件。但是,如果您打算同時使用__InstanceDeletionEvent和__InstanceCreationEvent,則應該訂閱__InstanceOperationEvent,然後通過評估e.NewEvent.ClassPath.ClassName屬性來檢查回調哪個事件。 – Hans 2012-01-15 09:33:36
沒有必要監視任何東西。您只需要枚舉進程並從進程實例StartTime中獲取。
但你當然必須使用計時器或類似的東西?枚舉一次流程是不夠的。所以,我不明白你爲什麼投下我的答案? – Hans 2012-01-15 09:05:38
有辦法實現它沒有計時器。您的答案的主要問題是,使用「__InstanceCreationEvent WITHIN 1」,您每秒都會進行輪詢。如果一個進程在這段時間內啓動並停止,您將永遠不會收到任何通知。如果您知道要檢查哪個進程,則在使用映像文件執行選項時可以從OS獲得回調。但是,第一個Farzan應該說明他如何獲得有問題的流程,哪些對他來說很有趣。有很多方法可以實現這一點。 – 2012-01-15 09:14:16
是的,我是aggree。有許多解決方案,如圖像文件執行選項,掛鉤,使用定時器輪詢,使用WMI或使用驅動程序。所以,我真的不明白你的投票。 – Hans 2012-01-15 09:28:28
- 1. 投票腳本(註冊和未註冊用戶)的最佳做法是什麼?
- 2. 打破長時間運行存儲過程的最佳方法是什麼?
- 3. 開始學習Android開發的最佳方式是什麼?
- 4. 開始開發大型網站的最佳方式是什麼?
- 5. 需要知道什麼是註冊命令的最佳做法
- 6. 處理「打開文件過多」的最佳方法是什麼?
- 7. 什麼是查找開始和結束時間數組之間的間隔的最佳方法
- 8. 什麼是開源的最佳方式?
- 9. 在WinForms中使用時間的最佳方法是什麼?
- 10. 什麼是計算時間跨度的最佳方法?
- 11. 確保初始化過程中存在屬性的最佳方法是什麼?
- 12. 在.NET中註冊現有Windows服務的最佳方法是什麼?
- 13. 什麼是檢查時間是否在一定時間內的最佳方法?
- 14. 開始使用NHibernate的最佳方式是什麼?
- 15. 從jQuery開始的最佳方式是什麼?
- 16. 開始使用MAPI的最佳方式是什麼?
- 17. 什麼是回到腳本開始的最佳方式?
- 18. 什麼是開始使用Asterisk的最佳方式?
- 19. 開始使用Lift的最佳方式是什麼?
- 20. 實現線程定時器的最佳方法是什麼
- 21. 從Node.js公開方法的最佳方式是什麼?
- 22. 測量android應用程序的性能時間的最佳方法是什麼?
- 23. ANTLR4的最佳方法是什麼?
- 24. 評論的最佳方法是什麼?
- 25. 將物業注入Sling模型的最佳方法是什麼?
- 26. 防止SQL注入mysql的最佳方法是什麼
- 27. 什麼是爲我的非智能手機開始編程的最佳方式?
- 28. 初始化ArrayList和HashMap的最佳方法是什麼?
- 29. 初始化類成員的最佳方法是什麼?
- 30. 初始化應用程序的最佳方式是什麼?
是的,由於許多原因,恆定輪詢是錯誤的解決方案,其中最重要的是性能下降。你正在尋找一個鉤子。但是你不能在C#中編寫鉤子DLL;你需要爲此使用C或C++。 – 2012-01-15 08:08:18
你的實際目標是什麼?很難給你一個解決你的問題的答案。你想監視任何過程開始還是僅僅啓動特定過程?您是否需要準確獲取受監視流程的運行時間,或者您只對運行時間較長的流程感興趣10分鐘?根據您的答案,可能會發現輪詢是一個「足夠好」的折衷。有確切的方法來做到這一點,但這些要複雜得多。 – 2012-01-15 11:15:32
對不起,**英語對我來說很難**。我想計算運行進程的時間並將其註冊到txt文件中。但我不想每秒檢查一次。 – 2012-01-15 11:32:26