我想開發一個應用程序(它可以隨時在後臺運行)來跟蹤應用程序(msword,excel,powerpoint,* .exe等)的使用情況。如何跟蹤應用程序使用情況?
我可以處理將數據發佈到數據庫,但並不知道從何處開始監視正在運行的應用程序(何時啓動,何時停止)。任何人有任何線索?
我想開發一個應用程序(它可以隨時在後臺運行)來跟蹤應用程序(msword,excel,powerpoint,* .exe等)的使用情況。如何跟蹤應用程序使用情況?
我可以處理將數據發佈到數據庫,但並不知道從何處開始監視正在運行的應用程序(何時啓動,何時停止)。任何人有任何線索?
您可以使用System.Diagnostics.Process.GetProcesses()
定期輪詢正在運行的進程的列表。
以下代碼輸出關於啓動和退出進程的信息。退出系統進程將無法識別。
class Program
{
struct ProcessStartTimePair
{
public Process Process { get; set; }
public DateTime StartTime { get; set; }
public DateTime ExitTime
{
get
{
return DateTime.Now; // approximate value
}
}
public ProcessStartTimePair(Process p) : this()
{
Process = p;
try
{
StartTime = p.StartTime;
}
catch (System.ComponentModel.Win32Exception)
{
StartTime = DateTime.Now; // approximate value
}
}
}
static void Main(string[] args)
{
List<ProcessStartTimePair> knownProcesses = new List<ProcessStartTimePair>();
while (true)
{
foreach (Process p in Process.GetProcesses())
{
if (!knownProcesses.Select(x => x.Process.Id).Contains(p.Id))
{
knownProcesses.Add(new ProcessStartTimePair(p));
Console.WriteLine("Detected new process: " + p.ProcessName);
}
}
for (int i = 0; i < knownProcesses.Count; i++)
{
ProcessStartTimePair pair = knownProcesses[i];
try
{
if (pair.Process.HasExited)
{
Console.WriteLine(pair.Process.ProcessName + " has exited (alive from {0} to {1}).", pair.StartTime.ToString(), pair.ExitTime.ToString());
knownProcesses.Remove(pair);
i--; // List was modified, 1 item less
// TODO: Store in the info in the database
}
}
catch (System.ComponentModel.Win32Exception)
{
// Would have to check whether the process still exists in Process.GetProcesses().
// The process probably is a system process.
}
}
Console.WriteLine();
System.Threading.Thread.Sleep(1000);
}
}
}
您可能簡單地忽略不允許您閱讀HasExited屬性的系統進程。
編輯
下面是一個.NET 2.0的版本:
static void Main(string[] args)
{
List<ProcessStartTimePair> knownProcesses = new List<ProcessStartTimePair>();
while (true)
{
foreach (Process p in Process.GetProcesses())
{
if (!ProcessIsKnown(knownProcesses, p.Id))
{
knownProcesses.Add(new ProcessStartTimePair(p));
Console.WriteLine("Detected new process: " + p.ProcessName);
}
}
for (int i = 0; i < knownProcesses.Count; i++)
[...]
}
}
static bool ProcessIsKnown(List<ProcessStartTimePair> knownProcesses, int ID)
{
foreach (ProcessStartTimePair pstp in knownProcesses)
{
if (pstp.Process.Id == ID)
{
return true;
}
}
return false;
}
注意,代碼可以改善,只能說明這個概念。
您可以定期輪詢所有頂級窗口並記錄窗口標題文本;並在此基礎上就運行哪個程序做出一些結論。
或者你可以通過進程名稱或組合來完成。
有關枚舉窗口,請參見http://msdn.microsoft.com/en-us/library/ms633497(VS.85).aspx和here is how to use it in managed code。 若要枚舉進程,請使用Process.GetProcesses方法或參見http://www.codeproject.com/KB/threads/enumprocess.aspx
輪詢是容易的,但你真的應該掛鉤到win32的事件,而是接受當這些事情發生的通知。
我有一個類似的邊項目來創建一個「任務欄」類型的應用程序。我的目標是在窗口移動/創建/關閉時通知應用程序,以便我可以使用此信息來顯示/更新UI。
bb4win程序有這個「層」它可以捕捉不同種類的系統通知,並使用它來創建一個替代桌面外殼。源代碼是可用的,並用c編碼。
這是我以前用Win32 Hooks開始的鏈接。
它可以使用通知WMI當流程啓動/退出
A full working example is in a blog post on ASP.NET。
它的基本功能(從博客帖子後人複製):
創建一個類,從ManagementEventWatcher
在構造函數中繼承,設置:
this.Query.QueryLanguage = "WQL";
this.Query.QueryString = @"SELECT * FROM
__InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'";
this.EventArrived += watcher_EventArrived; // Delegate for EventArrivedEventHandler
private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
string eventType = e.NewEvent.ClassPath.ClassName;
Win32_Process proc = new
Win32_Process(e.NewEvent["TargetInstance"] as ManagementBaseObject);
switch (eventType)
{
case "__InstanceCreationEvent":
Console.WriteLine("Process Created");
break;
case "__InstanceDeletionEvent":
Console.WriteLine("Process Deleted (Ended)");
break;
case "__InstanceModificationEvent":
Console.WriteLine("Process Modified (possibly still running)");
break;
}
}
當進程dis出現?你需要每分鐘輪詢一分鐘才能獲得1分鐘的分辨率嗎? – 2009-06-23 20:39:39