2009-06-09 16 views
17

私は、アプリケーションの機能のいくつかを動作させるために、アプリケーションの実行が必要なサービスをいくつか持っています。アプリケーションの起動後に外部Windowsサービスを初期化するだけのオプションを有効にしたいと考えています。 (アプリケーションを必要としないときに自動的にマシンを起動してメモリを使用するのではなく)exeが起動したときの監視

これを実装するためにexeのコードにアクセスできないので、理想的にはC#.Net exeが起動されたときに監視するWindowsサービス。

私が今までに見つけたのは、System.IO.FileSystemEventHandlerです。このコンポーネントは、変更、作成、削除、名前変更されたイベントタイプのみを処理します。私は、ファイルシステムコンポーネントが私が探しているものを見つけるのに理想的な場所だとは思っていませんが、どこに行くのか分かりません。

多分私は適切なキーワードで検索しているわけではありませんが、私はまだGoogleやstackoverflow.comで非常に有用なものは見つけていません。それが来るとき

ソリューションは... XP、Vista、および勝利7上で実行するために、任意のポインタを事前に

感謝を必要とされるであろう。

答えて

26

this articleから、サービスでWMI(名前空間System.Management)を使用してプロセスの開始イベントを監視できます。

void WaitForProcess() 
{ 
    ManagementEventWatcher startWatch = new ManagementEventWatcher(
     new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace")); 
    startWatch.EventArrived 
         += new EventArrivedEventHandler(startWatch_EventArrived); 
    startWatch.Start(); 

    ManagementEventWatcher stopWatch = new ManagementEventWatcher(
     new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace")); 
    stopWatch.EventArrived 
         += new EventArrivedEventHandler(stopWatch_EventArrived); 
    stopWatch.Start(); 
} 

    static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) { 
    stopWatch.Stop(); 
    Console.WriteLine("Process stopped: {0}" 
         , e.NewEvent.Properties["ProcessName"].Value); 
    } 

    static void startWatch_EventArrived(object sender, EventArrivedEventArgs e) { 
    startWatch.Stop(); 
    Console.WriteLine("Process started: {0}" 
         , e.NewEvent.Properties["ProcessName"].Value); 
    } 
} 

WMIでは、かなり洗練されたクエリが可能です。監視しているアプリが起動したとき、または他の条件でイベントハンドラを起動するために、ここでクエリを変更することができます。 Here's a quick introduction、C#の観点から。

+0

優れた答え。私の問題を解決しました。 – Stimul8d

+0

優れた、非常に便利です。乾杯! – tjjjohnson

+1

Windows 7でこのコードを実行する際に問題が発生しました。startWatch.Start()を呼び出すときに「アクセスが拒否されました」というエラーが表示されます。誰かがそれのためのworkarounを見つけましたか? – tjjjohnson

4

あなたはここに3つのオプションがあります。

信頼性/侵入一つは、アプリが起動されるたびに、C#のアプリに戻って通信をアンマネージコードでフックを設定します。これは正しいことが難しく、各プロセスに余分なDLLをロードする必要があります。 (あるいはドライバを作成することもできますが、書き込みがさらに難しくなります)

信頼性の低い方法では、すべてのプロセス(System.Diagnostics.Processクラスを使用)を定期的に(たとえば10〜30秒ごとに)リストしてアプリが起動されます。

Win32_Process、InstanceCreationEvent WMIイベントをマネージコードから見ることもできます。どれくらいの信頼性があるかはわかりませんが、プロセスをポーリングするよりも優れていると思われます。

0

プロセスが実行中であるかどうかを監視します。ただし、これを実行するには1つのサービスが実行されている必要があります。

本当にリソースを消費したくない場合は、単純なサービスをプレーンCで記述します。MFC/ATLなしで書かれたサービスアプリケーションは、300〜400 KBのメモリを消費し、CPUサイクルはほとんど使用できません。興味のあるプロセスが起動すると、C#サービスを起動できます。

0
public Process IsProcessOpen(string name) 
     { 
      foreach (Process clsProcess in Process.GetProcesses()) 
       if (clsProcess.ProcessName.Contains(name)) 
        return clsProcess; 
      return null; 
     } 
0

Windows 7の機能が動作していないと返信します。 64ビットプロセスを監視している場合は、64ビットアドレス空間でも動作するようにプロセスを構築する必要があります。

関連する問題