Einzelnen Beitrag anzeigen

Christian Seehase
(Co-Admin)

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

Re: Dienste auslesen und ggf. Werte ändern

  Alt 28. Mai 2004, 20:37
Moin F.W.,

hier mal ein Beispiel, wie man die sich die Services die als Starttype "Automatisch" haben in einem Memo anzeigen lassen kann.
Da ich teilweise etwas mit Borlands Deklarationen auf dem Kriegsfuss stehe, habe ich einen Teil der Funktionen/Strukturen selber deklariert. Zusätzlich muss noch die Unit WinSvc mit eingebunden werden.

Auf eine Kommentierung habe ich vorerst mal verzichtet. Schau es Dir einfach mal in Ruhe an, und versuch' mal nachzuvollziehen was da passiert.
Eines möchte ich allerdings schon vorab erklären:
Funktionen, die eine bestimmte Buffergrösse erfordern kann man mit gezielt zu kleinem Buffer aufrufen, damit sie einem zurückgeben wieviel Platz sie brauchen. Deshalb tauchen Funktionsaufrufe mehrfach auf.

Delphi-Quellcode:
type
  PENUM_SERVICE_STATUS = ^ENUM_SERVICE_STATUS;
  ENUM_SERVICE_STATUS = packed record
    lpServiceName : PCHAR;
    lpDisplayName : PCHAR;
    ServiceStatus : SERVICE_STATUS;
  end;

  PQUERY_SERVICE_CONFIG = ^QUERY_SERVICE_CONFIG;
  QUERY_SERVICE_CONFIG = packed record
    dwServiceType : DWORD;
    dwStartType : DWORD;
    dwErrorControl : DWORD;
    lpBinaryPathName : PCHAR;
    lpLoadOrderGroup : PCHAR;
    dwTagId : DWORD;
    lpDependencies : PCHAR;
    lpServiceStartName : PCHAR;
    lpDisplayName : PCHAR;
  end;

  function EnumServicesStatus(
    const hSCManager : DWORD;
    const dwServiceType : DWORD;
    const dwServiceState : DWORD;
    const lpServices : PENUM_SERVICE_STATUS;
    const cbBufSize : DWORD;
    const pcbBytesNeeded : PDWORD;
    const lpServicesReturned : PDWORD;
    const lpResumeHandle : PDWORD
    ) : Longbool; stdcall; external 'advapi32.dllname 'EnumServicesStatusA';

  function QueryServiceConfig(
    const hService : DWORD;
    const lpServiceConfig : PQUERY_SERVICE_CONFIG;
    const cbBufSize : DWORD;
    const pcbBytesNeeded : PDWORD
    ) : Longbool; stdcall; external 'advapi32.dllname 'QueryServiceConfigA';

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

var
  hSCDB : DWORD;
  hService : DWORD;
  pStatus : PENUM_SERVICE_STATUS;
  pWork : PENUM_SERVICE_STATUS;
  pServiceConfig : PQUERY_SERVICE_CONFIG;
  cbBufSize : DWORD;
  dwSaveBufSize : DWORD;
  pcbBytesNeeded : DWORD;
  lpServicesReturned : DWORD;
  lpResumeHandle : DWORD;
  i : integer;

begin
  hSCDB := OpenSCManager(nil,nil,SC_MANAGER_ENUMERATE_SERVICE or GENERIC_READ);
  if hSCDB = 0 then begin
    ShowMessage(SysErrorMessage(GetLastError));
    exit;
  end;
  try
    cbBufSize := 0;
    pStatus := nil;
    lpResumeHandle := 0;
    EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle);
    lpResumeHandle := 0;
    pStatus := AllocMem(pcbBytesNeeded);
    try
      cbBufSize := pcbBytesNeeded;
      dwSaveBufSize := cbBufSize;
      if not EnumServicesStatus(hSCDB,SERVICE_WIN32,SERVICE_STATE_ALL,pStatus,cbBufSize,@pcbBytesNeeded,@lpServicesReturned,@lpResumeHandle) then begin
        ShowMessage(SysErrorMessage(GetLastError));
        exit;
      end;
      pWork := pStatus;
      Memo1.Lines.Clear;
      for i := 1 to lpServicesReturned do begin
        hService := OpenService(hSCDB,pWork.lpServiceName,GENERIC_READ);
        if hService <> 0 then begin
          pServiceConfig := nil;
          cbBufSize := 0;
          pcbBytesNeeded := 0;
          QueryServiceConfig(hService,pServiceConfig,cbBufSize,@pcbBytesNeeded);
          pServiceConfig := AllocMem(pcbBytesNeeded);
          try
            cbBufSize := pcbBytesNeeded;
            if QueryServiceConfig(hService,pServiceConfig,cbBufSize,@pcbBytesNeeded) then begin
              if pServiceConfig.dwStartType = SERVICE_AUTO_START then begin
                Memo1.Lines.Add(pServiceConfig.lpDisplayName);
              end;
            end else begin
              ShowMessage(SysErrorMessage(GetLastError));
            end;
          finally
            if pServiceConfig <> nil then FreeMem(pServiceConfig,cbBufSize);
          end;
        end else begin
          ShowMessage(SysErrorMessage(GetLastError));
        end;
        inc(pWork);
      end;
    finally
      if pStatus <> nil then FreeMem(pStatus,dwSaveBufSize);
    end;
  finally
    CloseServiceHandle(hSCDB);
  end;
end;
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