AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Dienste und NotifyServiceStatusChangeW
Thema durchsuchen
Ansicht
Themen-Optionen

Dienste und NotifyServiceStatusChangeW

Ein Thema von stOrM · begonnen am 23. Aug 2011 · letzter Beitrag vom 9. Sep 2011
 
Benutzerbild von stOrM
stOrM

Registriert seit: 7. Jun 2003
Ort: Mülheim an der Ruhr
434 Beiträge
 
Delphi 10.3 Rio
 
#1

Dienste und NotifyServiceStatusChangeW

  Alt 23. Aug 2011, 03:29
Moin,
Ich stehe gerade ein wenig auf dem Schlauch und zwar würde ich gerne für ein Projekt mitbekommen ob irgendein Dienst gestartet oder beendet wurde.

Dazu dachte ich mir bieten sich 2 Dinge an:

Polling:
Was ich gerne vermeiden würde weil permanent über die Liste aller Dienste zu wandern und deren Status zu überprüfen, scheint mir nicht wirklich Resourcen schonend.

Callback über:
NotifyServiceStatusChangeW

Letzteres habe ich gerade mal versucht zu übersetzen:

Delphi-Quellcode:
const
  SERVICE_NOTIFY_CREATED = $00000080;
  SERVICE_NOTIFY_CONTINUE_PENDING = $00000010;
  SERVICE_NOTIFY_DELETE_PENDING = $00000200;
  SERVICE_NOTIFY_DELETED = $00000100;
  SERVICE_NOTIFY_PAUSE_PENDING = $00000020;
  SERVICE_NOTIFY_PAUSED = $00000040;
  SERVICE_NOTIFY_RUNNING = $00000008;
  SERVICE_NOTIFY_START_PENDING = $00000002;
  SERVICE_NOTIFY_STOP_PENDING = $00000004;
  SERVICE_NOTIFY_STOPPED = $00000001;
  SERVICE_NOTIFY_STATUS_CHANGE = $00000002;

type
  PFN_SC_NOTIFY_CALLBACK = function(pvParameter: Pointer): DWORD; stdcall;
  TPFN_SC_NOTIFY_CALLBACK = PFN_SC_NOTIFY_CALLBACK;

type
  _SERVICE_STATUS_PROCESS = record
    dwServiceType, dwCurrentState, dwControlsAccepted, dwWin32ExitCode,
      dwServiceSpecificExitCode, dwCheckPoint, dwWaitHint, dwProcessId,
      dwServiceFlags: DWORD;
  end;
  SERVICE_STATUS_PROCESS = _SERVICE_STATUS_PROCESS;
  LPSERVICE_STATUS_PROCESS = ^_SERVICE_STATUS_PROCESS;
  TSERVICE_STATUS_PROCESS = _SERVICE_STATUS_PROCESS;

type
  _SERVICE_NOTIFYW = record
    dwVersion: DWORD;
    pfnNotifyCallback: TPFN_SC_NOTIFY_CALLBACK;
    pContext: PVOID;
    dwNotificationStatus: DWORD;
    ServiceStatus: SERVICE_STATUS_PROCESS;
    dwNotificationTriggered: DWORD;
    pszServiceNames: PChar;
  end;
  SERVICE_NOTIFYW = _SERVICE_NOTIFYW;
  PSERVICE_NOTIFYW = ^_SERVICE_NOTIFYW;
  TSERVICE_NOTIFYW = _SERVICE_NOTIFYW;
Da die GUI einfriert unter verwendung von SleepEx muß ich das ganze wohl in einen sep. Thread auslagern genau hier liegt eines der Probleme vor denen ich gerade stehe.

In der MSDN steht dazu:

Zitat:
The NotifyServiceStatusChange function can be used to receive notifications about service applications. It cannot be used to receive notifications about driver services.

When the service status changes, the system invokes the specified callback function as an asynchronous procedure call (APC) queued to the calling thread. The calling thread must enter an alertable wait (for example, by calling the SleepEx function) to receive notification. For more information, see Asynchronous Procedure Calls.
Gut dachte ich mir versuche ich das ganze mal mit WaitForMultipleObjectsEx.
Der Thread Funktioniert bei mir nun jetzt sagen wir mal teilweise.

Soll heißen, starte ich die Testanwendung, erhalte ich eine Information wenn irgendein Dienst gestartet oder beendet wurde. Soweit ja schon ok, nur das ich die Meldung nur ein einziges mal erhalte.

Bedeutet:
Anwendung startet Thread, Dienst wird gestartet oder beendet, ich bekomme eine Nachricht darüber. Wird jetzt noch ein Dienst gestartet oder beendet erhalte ich keine Nachricht mehr, Callback wird nicht mehr aufgerufen!

Meine Frage dazu wäre, wie muß ich mein WaitForMultipleObjectsEx aufbauen?
Wenn ich das Richtig sehe brauch ich mindestens 2 Events? Ein TerminateEvent (damit der Thread sauber beendet werden kann und nicht irgendwo hängen bleibt?) sowie ein weiteres Event welches sich um den Callback kümmert?

Ich hatte es vorher mal so angefangen:

Delphi-Quellcode:
  scManagerHandle := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);

  if srvManager = 0 then
    exit;

  GetMem(fNotifyBuffer, sizeof(PSERVICE_NOTIFYW));
  fNotifyBuffer^.dwVersion := SERVICE_NOTIFY_STATUS_CHANGE;
  fNotifyBuffer^.pfnNotifyCallback := CALLBACK;
  fNotifyBuffer.pContext := Pointer(nil);

  DResult := NotifyServiceStatusChangeW(scManagerHandle,
    SERVICE_NOTIFY_CREATED or SERVICE_NOTIFY_DELETED, fNotifyBuffer);

    while not Terminated do
  begin
    // nur für den thread selber gedacht, wenn ich den Thread von außen einfach beende der aber auf ein Alert wartet für den callback bleibt er hängen
    case WaitForMultipleObjectsEx(2, @ThreadHandles[0], FALSE, INFINITE, True) of
      WAIT_OBJECT_0 + 0:
        begin
          try
            exit;
          except

          end;

        end;
      WAIT_OBJECT_0 + 1:
        begin
            if DResult = ERROR_SUCCESS then
            begin
              // hier ist das Problem was mach ich hier nochmal ein WaitformultipleObjects einbauen?
              // Wenn ja, muß ich das Event dann im Callback resetten ?
              // Oder SleepEx ?
            end;
         end;
Also die Frage hier ist wie aus dem Kommentar in Wait_Object_0 +1 hervorgeht was mach ich da?
Da es ja funktionierte einmalig (war noch ein WaitforMultipleObjectsEx enthalten) geh ich davon aus das das Problem genau dort zu liegen scheint, heißt der Callback wird ausgeführt, nur ist der Thread danach wohl nicht mehr in Parkposition bzw. der Thread schon nur eben NotifyServiceStatusChangeW nicht mehr ...

Wäre super, wenn da mal jemand Licht in mein Dunkel bringen könnte.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:22 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz