2009-06-09 28 views
17

Mam pewne usługi, które wymagają uruchomienia aplikacji, aby niektóre funkcje aplikacji mogły działać. Chciałbym włączyć opcję uruchamiania zewnętrznych usług Windows w celu zainicjowania po uruchomieniu aplikacji. (w przeciwieństwie do uruchamiania ich automatycznie z maszyną i zajmowania pamięci, gdy aplikacja nie jest potrzebna)Monitorowanie po uruchomieniu exe

Nie mam dostępu do kodu exe, aby to zaimplementować, więc najlepiej byłoby napisać C# .Net Usługa Windows, która monitorowałaby uruchomienie exe.

Co znalazłem do tej pory jest System.IO.FileSystemEventHandler. Ten komponent obsługuje tylko zmienione, utworzone, usunięte i zmienione nazwy typów zdarzeń. Nie oczekuję, że komponent systemu plików byłby idealnym miejscem do znalezienia tego, czego szukam, ale nie wiem, gdzie jeszcze pójść.

Może nie szukam właściwych słów kluczowych, ale nie znalazłem jeszcze niczego niezwykle przydatnego w Google lub tutaj na stackoverflow.com.

Rozwiązaniem byłyby wymagane do uruchomienia na XP, Vista i Win 7, jeśli chodzi ...

Dzięki z góry za wszelkie wskazówki.

Odpowiedz

26

Od this article można używać usługi WMI (przestrzeń nazw System.Management) w usłudze, aby obejrzeć zdarzenia rozpoczęcia procesu.

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 pozwala na dość wyrafinowane zapytania; Możesz tutaj modyfikować zapytania, aby uruchomić procedurę obsługi zdarzenia tylko wtedy, gdy uruchomiona jest uruchomiona aplikacja lub na innych kryteriach. Here's a quick introduction, z perspektywy C#.

+0

Doskonała odpowiedź. rozwiązał mój problem. – Stimul8d

+0

Doskonały, bardzo przydatny. Twoje zdrowie! – tjjjohnson

+1

Masz problemy z wykonaniem tego kodu w systemie Windows 7. Otrzymuję błąd "odmowa dostępu" podczas wywoływania metody startWatch.Start(). Czy ktoś znalazł sposób na to? – tjjjohnson

4

masz 3 możliwości:

Niezawodne/natrętne jeden, założyć hak w niezarządzanego kodu, który komunikuje się z powrotem do swojej aplikacji C#, gdy aplikacja jest uruchomiona. Jest to trudne do uzyskania i wymaga załadowania dodatkowej biblioteki DLL dla każdego procesu. (Alternatywnie można ustawić sterownik, który jest jeszcze trudniejszy do napisania)

W mniej wiarygodny sposób wszystkie procesy (przy użyciu klasy System.Diagnostics.Process) wymieniać regularnie (na przykład co 10-30 sekund), aby sprawdzić, czy aplikacja zostanie uruchomiona.

Możliwe jest również oglądanie zdarzenia Win32_Process, InstanceCreationEvent WMI z kodu zarządzanego. Nie jestem pewny, na ile jest to wiarygodne, ale podejrzewam, że byłby lepszy niż procesy odpytywania.

0

Monitoruj, czy proces jest uruchomiony - do tego celu musi być uruchomiona jedna usługa.

Jeśli naprawdę nie chcesz zużywać żadnych zasobów - napisz prostą usługę w zwykłym C. Aplikacja serwisowa napisana bez MFC/ATL może zużywać zaledwie 300-400 KB pamięci i wirtualnie nie ma cykli procesora. Kiedy proces, którym jesteś zainteresowany, uruchamia się, możesz odrodzić swoje usługi C#.

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

W odpowiedzi na aspekt Windows 7 nie działa. Jeśli monitorujesz 64-bitowe procesy, twój proces musi zostać zbudowany, aby działał również w 64-bitowej przestrzeni adresowej.

Powiązane problemy