2009-06-23 11 views
1

アプリケーション(msword、excel、powerpoint、* .exeなど)の使用状況を追跡するためのアプリケーション(いつもバックグラウンドで実行される)を開発したいと考えています。アプリケーションの使用状況を追跡するにはどうすればよいですか?

データをデータベースにポストすることはできますが、実行中のアプリケーションの監視(開始時、停止時)から開始する場所を正確には把握できません。誰でも手がかりはありますか?

答えて

3

を参照してください。

次のコードは、プロセスの開始と終了に関する情報を出力します。終了しているシステムプロセスは認識されません。

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プロパティを読み取らせないシステムプロセスは無視できます。コードが改善され、唯一の概念を示していることができることを

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

注:

編集

はここで.NET 2.0バージョンです。

+0

プロセスがdis表示されますか?あなたは1分の解像度を得るために1分ごとにポーリングする必要がありますか? –

+0

はい、それのために毎分を引き出す必要があります。既存のすべてのプロセスをリストに保存し、新しいプロセスが存在するかどうか、またはそれらのプロセスの一部が終了しているかどうかを確認します。 – weiqure

+0

ええ、私は、アプリケーションが終了するとExitTimeが(実行されていないので)傍受されないと思います。私は、ユーザー 'jdoe'が7月に合計44分間、Excelで使用されたと言うことができるようにしたいと思っています – Jason

1

すべてのトップレベルウィンドウを定期的にポーリングして、ウィンドウのタイトルテキストを記録することができます。それに基づいて、どのプログラムが実行されているかに関するいくつかの結論を出す。

または、プロセス名またはその組み合わせで実行できます。

ウィンドウを列挙するには、http://msdn.microsoft.com/en-us/library/ms633497(VS.85).aspxおよびhere is how to use it in managed codeを参照してください。列挙プロセスのために 、Process.GetProcessesメソッドを使用するか、あなたが定期的にSystem.Diagnostics.Process.GetProcesses()を使用して、実行中のプロセスのリストをポーリングすることができhttp://www.codeproject.com/KB/threads/enumprocess.aspx

0

ポーリングは簡単ですが、実際にはwin32イベントにフックし、代わりにこれらの状況が発生したときの通知を受け取る必要があります。

「タスクバー」タイプのアプリケーションを作成するのと同様のサイドプロジェクトがあります。私の目標は、UIを表示/更新するためにこの情報を使用できるように、ウィンドウの移動/作成/終了時にアプリに通知することです。

bb4winアプリには、システムからのさまざまな種類の通知を受け取り、代わりのデスクトップシェルを作成するために使用するこの「レイヤー」があります。ソースコードは利用可能で、cでコード化されています。

これは私がWin32 Hooksで始めるために使用したリンクです。

1

これは、プロセスが/終了

A full working example is in a blog post on ASP.NETを起動したときに通知されるようにWMIを使用することが可能です。

(後世のためのブログ記事からコピーされた)、それの基礎:

this.Query.QueryLanguage = "WQL"; 
this.Query.QueryString = @"SELECT * FROM 
__InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"; 
this.EventArrived += watcher_EventArrived; // Delegate for EventArrivedEventHandler 

EventArrivedEventHandlerなどを行います。

が設定され、コンストラクタの内部ManagementEventWatcher

を継承するクラスを作成します。 :

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; 
    } 
} 
関連する問題