Einzelnen Beitrag anzeigen

Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Remote Services listen / neuen Dienst installieren

  Alt 5. Mai 2004, 16:50
Moin KRO,

ich hab' hier mal ein Beispiel, wie das geht, aus einem Programm extrahiert:

Delphi-Quellcode:
type
  // für selbstimportierte Funktion erforderlich
  PENUM_SERVICE_STATUS = ^TEnumServiceStatus;

  // Funktion selber importieren, da die Borland Version nur den ersten zugreifbar macht
  function EnumServicesStatus(
    const hSCManager : DWord; // handle to SCM database
    const dwServiceType : DWord; // service type
    const dwServiceState : DWord; // service state
    const lpServices : PENUM_SERVICE_STATUS; // status buffer
    const cbBufSize : DWord; // size of status buffer
    const pcbBytesNeeded : PDWORD; // buffer size needed
    const lpServicesReturned : PDWord; // number of entries returned
    const lpResumeHandle : PDWord // next entry
    ) : Boolean; stdcall; external 'advapi32.dllname 'EnumServicesStatusA';

implementation

{$R *.DFM}

procedure EnumServices(const AsComputerName : string);

var
  hSCDB : DWORD;
  pStatus : PENUM_SERVICE_STATUS;
  pWork : PENUM_SERVICE_STATUS;
  cbBufSize : DWORD;
  pcbBytesNeeded : DWORD;
  lpServicesReturned : DWORD;
  lpResumeHandle : DWORD;
  iCount : integer;

begin
  Form1.ListBox1.Items.Clear;
  hSCDB := OpenSCManager(
    PChar('\\'+AsComputerName), // Dienste des angegebenen Rechners auslesen
    nil, // Standarddatenbank nehmen
    SC_MANAGER_ENUMERATE_SERVICE // Dienste aufzählen (alle durchgehen)
      or // ausserdem
    GENERIC_READ); // genügt es die Daten nur zu lesen
  if hSCDB <> 0 then begin
    try
      // Erforderlichen Speicherplatz für alle Daten von der Funktion ermitteln lassen
      // ==> gezielt mit 0 Byte Buffer fehlschlagen lassen
      cbBufSize := 0;
      pStatus := nil;
      lpResumeHandle := 0;
      EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle);
      lpResumeHandle := 0;

      // speicher reservieren
      pStatus := AllocMem(pcbBytesNeeded);
      try
        cbBufSize := pcbBytesNeeded;
        EnumServicesStatus(
          hSCDB, // Handle von OpenSCManager
          SERVICE_WIN32, // Nur Dienste, keine Treiber
          SERVICE_STATE_ALL, // Alle installierten Dienste, egal ob sie laufen oder nicht
          pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle);
        // Adresse merken, damit der Speicher später wieder freigegeben werden kann, ohne den Pointer
        // wieder zurückrechnen zu müssen
        pWork := pStatus;
        // Alle Dienste in Listbox anzeigen (mit Namen und Anzeigenamen)
        for iCount := 1 to lpServicesReturned do begin
          Form1.ListBox1.Items.Add(pWork.lpServiceName+'/'+pWork.lpDisplayName);
          inc(pWork);
        end;
      finally
        if Assigned(pStatus) then FreeMem(pStatus,pcbBytesNeeded);
      end;
    finally
      CloseServiceHandle(hSCDB);
    end;
  end;
end;
[EDIT]
Nicht die vergessen die Unit winsvc mit einzubinden
[/EDIT]
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat