Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Mit Programm fremden Service/Dienste beenden und starten (https://www.delphipraxis.net/88528-mit-programm-fremden-service-dienste-beenden-und-starten.html)

Ares 16. Mär 2007 18:15


Mit Programm fremden Service/Dienste beenden und starten
 
Hallo!

Wie kann ich aus meinem Programm heraus einen fremden Service (z.B. den Service für die Automatischen Updates) beenden und starten? Welche Informationen sind notwendig um den Service "anzusprechen" und wie wird er dann kontrolliert?

Hier gibt es zwar einige Artikel über das Sarten und Beenden von Diensten, dabei geht es aber immer um selbstgeschriebene Services. Zu der Frage wie ich einen fremden Service kontrolliere habe ich leider noch keine Antwort gefunden.

Besten Dank!

mkinzler 16. Mär 2007 18:18

Re: Mit Programm fremden Service/Dienste beenden und starten
 
Die einfachste Möglichkeit wäre "net stop/start <Servicename>" per ShellExecute auzurufen

Ares 17. Mär 2007 07:19

Re: Mit Programm fremden Service/Dienste beenden und starten
 
Vielen Dank für den Tipp, das funktioniert prima! Gibt es eine ähnlich einfache Möglichkeit um herauszufinden, ob ein Dienst überhaupt gestartet ist?

Wenn man den net start/stop Befehl in einem cmd-Fenster ausführt erhält man Rückmeldunge wie "XYZ wurde erfolgreich gestartet/beende", "Systemfehler 1060 aufgetreten, Der angegebene Dienst ist kein installierter Dienst", etc. Kann ich diese Rückgaben bei einem ShellExecute irgendwie "auffangen" und auswerten?

mkinzler 17. Mär 2007 08:47

Re: Mit Programm fremden Service/Dienste beenden und starten
 
Werte doch die Rückgabe aus
http://www.dsdt.info/tipps/?id=422

Ares 17. Mär 2007 09:48

Re: Mit Programm fremden Service/Dienste beenden und starten
 
Hallo!

Ich will, dass mein Programm wartet bis der Service gestartet bzw. beendet wurde. Daher habe ich nicht ShellExecute sondern CreateProcess verwendet:

Delphi-Quellcode:
function startStopService(aServiceName: String; start:boolean): Boolean;
var Err: Integer;
    command: string;
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
begin
   if start then command := 'start ' else command := 'stop ';

   try
      FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
      StartupInfo.cb         := SizeOf(TStartupInfo);
      StartupInfo.dwFlags    := STARTF_USESHOWWINDOW;
      StartupInfo.wShowWindow := 0;

      CreateProcess(
         nil,
         PChar('net '+command+'"'+aServiceName+'"'),
         nil,
         nil,
         false,
         CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
         nil,
         nil,
         StartupInfo,
         ProcessInfo
      );

      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      CloseHandle(ProcessInfo.hProcess);
      //showMessage(IntToStr(Err));
   except

   end;
end;
Wie komme ich dort an die Rückgabe um diese auszuwerten?

Die Funktion funktioniert sonst gut, das Programm wartet brav und die Dienste lassen sich starten und beenden. Allerdings dauert das Starten/Beenden immer ein paar Sekunden. In dieser Zeit ist das Programm nicht bedienbar. Der Nutzer soll zwar keine Eingaben machen können, aber man sollte das Fenster zumindest verschieben und minimieren können. Ist das machbar oder geht das wegen des Wartens auf keinen Fall?

Besten Dank

Luckie 17. Mär 2007 12:26

Re: Mit Programm fremden Service/Dienste beenden und starten
 
Service starte, Service stoppen und Servicestatus abfragen:
Delphi-Quellcode:
uses
  windows, WinSvc;

const
  bit29 = 1 SHL 28;

  NERR_Success = 0;
  NERR_BASE = 2100;
  NERR_NameNotFound = NERR_BASE + 173;
  NERR_NetworkError = NERR_BASE + 36;
  ERROR_FAILED_STARTING_SERVICE = 1 or bit29;
  ERROR_FAILED_STOPPING_SERVICE = 2 or bit29;

// ..

////////////////////////////////////////////////////////////////////////////////
// Procedure : ServiceGetStatus
// Comment  : Author: DieHardMan

function ServiceGetStatus(sMachine, sService: PChar): DWORD;
  {******************************************} 
  {*** Parameters: ***} 
  {*** sService: specifies the name of the service to open
  {*** sMachine: specifies the name of the target computer
  {*** ***} 
  {*** Return Values: ***} 
  {*** -1 = Error opening service ***} 
  {*** 1 = SERVICE_STOPPED ***} 
  {*** 2 = SERVICE_START_PENDING ***} 
  {*** 3 = SERVICE_STOP_PENDING ***} 
  {*** 4 = SERVICE_RUNNING ***} 
  {*** 5 = SERVICE_CONTINUE_PENDING ***} 
  {*** 6 = SERVICE_PAUSE_PENDING ***} 
  {*** 7 = SERVICE_PAUSED ***} 
  {******************************************} 
var
  SCManHandle, SvcHandle: SC_Handle;
  SS: TServiceStatus;
  dwStat: DWORD;
begin
  dwStat := 0;
  // Open service manager handle.
  SCManHandle := OpenSCManager(sMachine, nil, SC_MANAGER_CONNECT);
  if (SCManHandle > 0) then
  begin
    SvcHandle := OpenService(SCManHandle, sService, SERVICE_QUERY_STATUS);
    // if Service installed
    if (SvcHandle > 0) then
    begin
      // SS structure holds the service status (TServiceStatus);
      if (QueryServiceStatus(SvcHandle, SS)) then
        dwStat := ss.dwCurrentState;
      CloseServiceHandle(SvcHandle);
    end;
    CloseServiceHandle(SCManHandle);
  end;
  Result := dwStat;
end;

function ServiceRunning(sMachine, sService: PChar): Boolean;
begin
  Result := SERVICE_RUNNING = ServiceGetStatus(sMachine, sService);
end;


function ServiceStart(Machine, ServiceName: string): Boolean;
// Machine is UNC path or local machine if empty
var
  h_manager, h_svc: SC_Handle;
  ServiceStatus: TServiceStatus;
  dwCheckPoint: DWORD;
  ServiceArgVectors: PChar;
begin
  h_manager := OpenSCManager(PChar(Machine), nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager, PChar(ServiceName),
      SERVICE_START or SERVICE_QUERY_STATUS or SC_MANAGER_ALL_ACCESS);
    if h_svc > 0 then
    begin
      if (StartService(h_svc, 0, ServiceArgVectors)) then { succeeded }
      begin
        if (QueryServiceStatus(h_svc, ServiceStatus)) then
        begin
          while (SERVICE_RUNNING <> ServiceStatus.dwCurrentState) do
          begin
            dwCheckPoint := ServiceStatus.dwCheckPoint;
            Sleep(ServiceStatus.dwWaitHint);
            if (not QueryServiceStatus(h_svc, ServiceStatus)) then
              // couldn't check status
              break;
            if (ServiceStatus.dwCheckPoint < dwCheckPoint) then
              break;
          end;
        end;
      end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;

  Result := (SERVICE_RUNNING = ServiceStatus.dwCurrentState);
end;

function ServiceStop(Machine, ServiceName: string): Boolean;
// Machine is UNC path or local machine if empty
var
  h_manager, h_svc: SC_Handle;
  ServiceStatus: TServiceStatus;
  dwCheckPoint: DWORD;
begin
  h_manager := OpenSCManager(PChar(Machine), nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager, PChar(ServiceName),
      SERVICE_STOP or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      if (ControlService(h_svc, SERVICE_CONTROL_STOP, ServiceStatus)) then
      begin
        if (QueryServiceStatus(h_svc, ServiceStatus)) then
        begin
          while (SERVICE_STOPPED <> ServiceStatus.dwCurrentState) do
          begin
            dwCheckPoint := ServiceStatus.dwCheckPoint;
            Sleep(ServiceStatus.dwWaitHint);
            if (not QueryServiceStatus(h_svc, ServiceStatus)) then
              // couldn't check status
              break;
            if (ServiceStatus.dwCheckPoint < dwCheckPoint) then
              break;
          end;
        end;
      end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;

  Result := (SERVICE_STOPPED = ServiceStatus.dwCurrentState);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:55 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz