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 Dienst-Management 4 dummies (https://www.delphipraxis.net/34165-dienst-management-4-dummies.html)

Ajintaro 18. Nov 2004 13:47


Dienst-Management 4 dummies
 
Hi liebe Delphi-Coder!

da ich nicht soo der Programmier-Held bin und bei meinem aktuellen tool net weiterkomme, erbitte ich die Hilfe der DP-Gurus hier in diesen heiligen Hallen. (hmpf, hab zuviel DAOC gezockt, sry)

Okay, okay. Ich möchte lediglich ein Prögrämmchen schreiben, den Dienst-Status grafisch darstellt. Quasi eine Form mit einem Panel für z.B. den allseits beliebten Nachrichtendienst. Ist der Dienst gestartet, hat das Panel die Farbe grün (Für OK). So ist der Dienst down dann hat das Panel die Farbe rot. Wenn der Dienst grad versucht wird zu starten dann gelb...
Dann sollte noch die Möglichkeit bestehen eben genau dies zu Managen. Klick auf das rote Panel = "Möchten sie den Dienst starten?" bzw. Klick aufs grüne Panel = Dienst stoppen?

Das ganze drumherum mit der Form und dem Panel ist ja kein Ding - nur die Dienste sind für mich wie die Relikte aus Albion.

Nein jetzt net ausflippen, hab mich totgesucht und einiges gefunden. Interessant klang der ServiceManager von den Swiss-Delphi Leuten. Ich kann den Servicemanager in mein Programm einbinden, jedoch leider kann ich keine Funktion davon aufrufen... Irgendwie gibts da Fehler und soo 100%tig steig ich da net durch. *heul*

Hier wird oft über Dienstmanagement gesprochen, aber so ein konkretes Beispiel Proggie oder gut erklärte Source hab ich nicht gefunden.

Falls ihr irgendwie Rat wisst wäreich sehr dankbar.

Gruss JJ

sakura 18. Nov 2004 13:59

Re: Dienst-Management 4 dummies
 
Ich habe hier mal eine Unit gepostet, die das recht einfach macht.

Mit der Methode ServiceGetStatus ermittelst Du den Status, die Rückgabewerte sind wie folgend:
Delphi-Quellcode:
//
// Service State -- for CurrentState
//
  {$EXTERNALSYM SERVICE_STOPPED}
  SERVICE_STOPPED               = $00000001;
  {$EXTERNALSYM SERVICE_START_PENDING}
  SERVICE_START_PENDING         = $00000002;
  {$EXTERNALSYM SERVICE_STOP_PENDING}
  SERVICE_STOP_PENDING          = $00000003;
  {$EXTERNALSYM SERVICE_RUNNING}
  SERVICE_RUNNING               = $00000004;
  {$EXTERNALSYM SERVICE_CONTINUE_PENDING}
  SERVICE_CONTINUE_PENDING      = $00000005;
  {$EXTERNALSYM SERVICE_PAUSE_PENDING}
  SERVICE_PAUSE_PENDING         = $00000006;
  {$EXTERNALSYM SERVICE_PAUSED}
  SERVICE_PAUSED                = $00000007;
Die Methoden ServiceStart/ServiceStop sind zum Starten und Stoppen von Diensten.

...:cat:...

Ajintaro 18. Nov 2004 14:43

Re: Dienst-Management 4 dummies
 
Ja dieses File von dir hab ich auch mal in ein Testproggie eingebunden.

Aber der Aufruf ist noch so ein Ding:

Delphi-Quellcode:
ServiceGetStatus(sMachine, sService: AnsiString): DWord;
sMachine ist das der PC-name? sService wär dann z.B. 'nachrichtendienst'

Delphi-Quellcode:
.....
begin
 ServiceGetStatus('mypc', 'nachrichtendienst');
end;
:gruebel:

sakura 18. Nov 2004 14:48

Re: Dienst-Management 4 dummies
 
Liste der Anhänge anzeigen (Anzahl: 1)
Für die Machine kannst Du imho, auch einen leeren String oder '.' (also einen Punkt) übergeben, wenn es der gleiche PC ist. Du musst allerdings auch die Rechte haben den Dienst zu starten/beenden. Der Dienstname des Nachrichtendienstes ist nicht sein Anzeigename, sondern der Registrierungsname, also Messenger (siehe Screen Shot).

...:cat:...

Ajintaro 18. Nov 2004 15:15

Re: Dienst-Management 4 dummies
 
stimmt!! Taadaaa! Jetzt kann ich wirklich den Nachrichtendienst stoppen und wieder starten :lol:

Jetzt muss ich nur moch im Form1.Create den Dienst-Status anzeigen lassen. Ich dachte an sowas:

Delphi-Quellcode:
procedure TForm1.Create(Sender: TObject)
begin
 if GetStatusService('', 'Messenger') then Panel1.Caption := clGreen;
end;
Hmm oder eine bool-variable erstellen und mir den Result der GetStatusService da reinschreiben?

sakura 18. Nov 2004 15:23

Re: Dienst-Management 4 dummies
 
Eher wie folgend:

Delphi-Quellcode:
uses
  WinSvc;

procedure TForm1.ShowStatus
begin
  case GetStatusService('', 'Messenger') of
    SERVICE_STOPPED, SERVICE_PAUSED:
      Panel1.Caption := 'angehalten';
    SERVICE_RUNNING:
      Panel1.Caption := 'läuft';
    SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING:
      Panel1.Caption := 'Status wird gerade geändert';
  else
    Panel1.Caption := 'Status ist unbekannt.';
  end;
end;
...:cat:...

Ajintaro 19. Nov 2004 08:51

Re: Dienst-Management 4 dummies
 
Guten Morgen!

gestern war ich leider schon weg, dehalb kam da keine Antwort mehr. Ich hab das tool fürs erste fertig bekommen dank dir Sakura!

so siehts aus:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uNTServiceControl, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Panel1: TPanel;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);

//    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//
// Service State -- for CurrentState
//
(*
  {$EXTERNALSYM SERVICE_STOPPED}
  SERVICE_STOPPED               = $00000001;
  {$EXTERNALSYM SERVICE_START_PENDING}
  SERVICE_START_PENDING         = $00000002;
  {$EXTERNALSYM SERVICE_STOP_PENDING}
  SERVICE_STOP_PENDING          = $00000003;
  {$EXTERNALSYM SERVICE_RUNNING}
  SERVICE_RUNNING               = $00000004;
  {$EXTERNALSYM SERVICE_CONTINUE_PENDING}
  SERVICE_CONTINUE_PENDING      = $00000005;
  {$EXTERNALSYM SERVICE_PAUSE_PENDING}
  SERVICE_PAUSE_PENDING         = $00000006;
  {$EXTERNALSYM SERVICE_PAUSED}
  SERVICE_PAUSED                = $00000007;
*)

procedure TForm1.Button1Click(Sender: TObject);
begin
 ServiceStop('', 'Messenger', true)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ServiceStart('', 'Messenger', true)
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
case ServiceGetStatus('', 'Messenger') of

  0: Panel1.Caption := 'Status 0';

  1: begin
        Panel1.Caption := 'gestoppt';
        Panel1.Color := clred;
     end;

  2: begin
       Panel1.Caption := 'wird gestartet';
       Panel1.Color := clyellow;
      end;

  3: Showmessage('3');

  4: begin
       Panel1.Caption := 'läuft';
       Panel1.Color := clGreen;
     end;
  5: Panel1.Caption := 'SERVICE_CONTINUE_PENDING'; //was auch immer das ist
  6: Panel1.Caption := 'SERVICE_PAUSE_PENDING'; //was auch immer das ist

  7: begin
       Panel1.Caption := 'pausiert';
       Panel1.Color := clteal;
     end;

  else
    Panel1.Caption := 'unbekannter Status';
  end;
end;
Es wird zuerst überprüft ob der Dienst (später die bestimmten Dienste) läuft und dann kann bequem gestartet oder gestoppt werden. Die Pause und den Neustart will ich noch einpflegen, sowie abhängige Dienste autoatisch mitstarten.

:stupid:

sakura 19. Nov 2004 08:54

Re: Dienst-Management 4 dummies
 
Bitte :-) Ein Tipp, die Konstanten der Art SERVICE_XXXXXX_PENDING, dass der Service gerade versucht den Status XXXXXX zu erreichen ;-)

...:cat:...

schuetze09 19. Nov 2004 10:10

Re: Dienst-Management 4 dummies
 
@sakura

hallo,

habe mir mal deine Unit genommen und das ganze ausprobiert, funktioniert wunderbar, aber wie kann ich einen deaktivierten Service starten?

mfg
schuetze09

sakura 19. Nov 2004 10:20

Re: Dienst-Management 4 dummies
 
Zitat:

Zitat von schuetze09
aber wie kann ich einen deaktivierten Service starten?

Gar nicht :zwinker: Du musst den zuerst aktivieren und dann kannst Du den auch starten. Habe ich noch nie versucht, aber in der Unit WinSvc ist die Funktion MSDN-Library durchsuchenChangeServiceConfig importiert, die sollte Dir die Möglichkeit geben den Service zu aktivieren. Anschließend kannst Du den auch starten.

...:cat:...

Ajintaro 19. Nov 2004 10:40

Re: Dienst-Management 4 dummies
 
..

schuetze09 19. Nov 2004 11:07

Re: Dienst-Management 4 dummies
 
habe eine lösung gefunden!!!
schaut euch mal die Unit an, da steht alles drin, in Bezug auf ChangeServiceConfig, funktiniert auch!
Delphi-Quellcode:
{
======================================================================
Project : Firebird utilities
Unit    : uService.pas
Purpose : Access the windows NT service manager API
Author  : Achim Kalwa <delphi@achim-kalwa.de>
Compiler : Borland Delphi 5.01
----------------------------------------------------------------------
Historie:
2002-03-04, Kalwa:
- Form/Unit created

2002-03-17, Kalwa:
- BUGFIX: In DoQueryServiceStatus, DoChangeServiceConfig,
  the memory allocated for PServiceConfig was never freed.
======================================================================
}

unit uService;

interface

uses
  SysUtils,
  Windows,
  WinSvc;

type
  TSvcStatus = (ssUnknown,               // enumeration of service status
                ssStopped,
                ssStartPending,
                ssStopPending,
                ssRunning,
                ssContinuePending,
                ssPausePending,
                ssPaused,
                ssError);

function GetWinSysDir : String;
function GetServiceStatus(ServiceName : String) : TSvcStatus;
function DoStartService(ServiceName : string) : TSvcStatus;
function DoStopService(ServiceName : string) : TSvcStatus;
function DoChangeServiceConfig(ServiceName : string; Enabled, AutoStart : Boolean) : Boolean;
function DoQueryServiceConfig(ServiceName : string; var DisplayName : string; var Enabled, AutoStart : Boolean) : Boolean;

implementation

uses
  Controls,
  Forms;

function GetWinSysDir : String;
var
  aLen  : Integer;
begin
  SetLength(Result, MAX_PATH);
  aLen := Windows.GetSystemDirectory(PChar(Result), MAX_PATH);
  SetLength(Result, aLen);
end;

function GetServiceStatus(ServiceName : String) : TSvcStatus;
{ retrieve status of given service }
var
  dwStatus        : DWord;
  hService        : SC_HANDLE;
  hServiceManager : SC_HANDLE;
  ServiceStatus   : TServiceStatus;
Begin
  dwStatus := 0 ;
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);

  if hServiceManager > 0 then begin
    hService := OpenService(hServiceManager,
                            pChar(ServiceName),
                            SERVICE_QUERY_STATUS);
    if hService > 0 then begin
      if QueryServiceStatus(hService, ServiceStatus) then begin
        dwStatus := ServiceStatus.dwCurrentState;
      end;
      CloseServiceHandle(hService) ;
    end;
  end;
  CloseServiceHandle(hServiceManager) ;
  Result := TSvcStatus(dwStatus);
end;                                   { GetServiceStatus }

function DoStartService(ServiceName : string) : TSvcStatus;
{ start a installed service by name. Returns the service status }
var
  hService        : SC_HANDLE;
  hServiceManager : SC_HANDLE;
  pDummy          : PChar;
  Tries           : Integer;
begin
  Result := GetServiceStatus(ServiceName);
  if Result <> ssStopped then Exit;

  Screen.Cursor := crHourGlass;
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);

  if hServiceManager > 0 then begin
    hService := OpenService(hServiceManager,
                            PChar(ServiceName),
                            SERVICE_START);
    if hService > 0 then begin
      pDummy := nil;
      if StartService(hService, 0, pDummy) then begin
        Tries := 10;
        repeat
          Sleep(1000);
          Result := GetServiceStatus(ServiceName);
          Dec(Tries);
        until (Tries = 0) or (Result = ssRunning);
      end
      else begin
        Result := ssError;
      end;
      CloseServiceHandle(hService);
    end;
  end;
  CloseServiceHandle(hServiceManager);
  Screen.Cursor := crDefault;
end; { DoStartService }

function DoStopService(ServiceName : string) : TSvcStatus;
{ stop a running service by name. Returns the service status }
var
  hService        : SC_HANDLE;
  hServiceManager : SC_HANDLE;
  ServiceStatus   : TServiceStatus;
  Tries           : Integer;
begin
  Result := GetServiceStatus(ServiceName);
  if Result <> ssRunning then Exit;

  Screen.Cursor := crHourGlass;
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if hServiceManager > 0 then begin
    hService := OpenService(hServiceManager,
                            PChar(ServiceName),
                            GENERIC_EXECUTE);
    if hService > 0 then begin
      if ControlService(hService, SERVICE_CONTROL_STOP, ServiceStatus) then begin
        Tries := 10;
        Repeat
          Sleep(1000);
          Dec(Tries);
          Result := GetServiceStatus(ServiceName);
        until (Tries = 0) or (Result = ssStopped);
      end
      else
        Result := ssError;

      CloseServiceHandle(hService);
    end;
  end;
  CloseServiceHandle(hServiceManager) ;
  Screen.Cursor := crDefault;
end;  { DoStopService }

function DoQueryServiceConfig(ServiceName : string; var DisplayName : string; var Enabled, AutoStart : Boolean) : Boolean;
{ retrieves information for a named service. }
var
  hService        : SC_HANDLE;
  hServiceManager : SC_HANDLE;
  BytesNeeded     : DWORD;
  PServiceConfig  : PQueryServiceConfig;
begin
  Result := False;
  DisplayName := '';
  Enabled    := False;
  AutoStart  := False;
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if hServiceManager > 0 then begin
    hService := OpenService(hServiceManager,
                            PChar(ServiceName),
                            SERVICE_QUERY_CONFIG or SERVICE_CHANGE_CONFIG);
    if hService > 0 then begin
      BytesNeeded := 0;
      QueryServiceConfig(hService, nil, 0, BytesNeeded);
      GetMem(PServiceConfig, BytesNeeded);
      QueryServiceConfig(hService, PServiceConfig, BytesNeeded, BytesNeeded);
      DisplayName := StrPas(PServiceConfig^.lpDisplayName);
      case PServiceConfig^.dwStartType of
        SERVICE_AUTO_START:
          begin
            Enabled := True;
            AutoStart := True;
          end;
        SERVICE_DEMAND_START:
          begin
            Enabled := True;
            AutoStart := False;
          end;
        SERVICE_DISABLED:
          begin
            Enabled := False;
            AutoStart := False;
          end;
      end; { case }
      CloseServiceHandle(hService);
      FreeMem(PServiceConfig);
    end;
  end;
  CloseServiceHandle(hServiceManager) ;
  Screen.Cursor := crDefault;
end;                                   { DoQueryServiceStatus }

function DoChangeServiceConfig(ServiceName : string; Enabled, AutoStart : Boolean) : Boolean;
{ changes a service's statup configuration } 
var
  hService        : SC_HANDLE;
  hServiceManager : SC_HANDLE;
  NewStartType    : Integer;
  DisplayName     : string;
  BytesNeeded     : DWORD;
  PServiceConfig  : PQueryServiceConfig;

begin
  Result := False;
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if hServiceManager > 0 then begin
    hService := OpenService(hServiceManager,
                            PChar(ServiceName),
                            SERVICE_QUERY_CONFIG or SERVICE_CHANGE_CONFIG);
    if hService > 0 then begin
      BytesNeeded := 0;
      QueryServiceConfig(hService, nil, 0, BytesNeeded);
      GetMem(PServiceConfig, BytesNeeded);
      QueryServiceConfig(hService, PServiceConfig, BytesNeeded, BytesNeeded);
      DisplayName := StrPas(PServiceConfig^.lpDisplayName);
      if Enabled then begin
        if AutoStart
        then NewStartType := SERVICE_AUTO_START
        else NewStartType := SERVICE_DEMAND_START;
      end
      else
        NewStartType := SERVICE_DISABLED;

      Result := ChangeServiceConfig(
        hService,                      { Handle of Service }
        SERVICE_NO_CHANGE,             { don't change service type }
        NewStartType,                  { set new start type }
        SERVICE_NO_CHANGE,             { don't change ErrorControl }
        nil,                           { don't change BinaryPathName }
        nil,                           { don't change LoadGroupOrder }
        nil,                           { don't change dwTagID }
        nil,                           { don't change Dependencies }
        nil,                           { don't change ServiceStartName }
        nil,                           { don't change Password (if any) }
        PChar(DisplayName));           { Display name }

      CloseServiceHandle(hService);
      FreeMem(PServiceConfig);
    end;
  end;
  CloseServiceHandle(hServiceManager) ;
  Screen.Cursor := crDefault;
end;                                   { DoChangeServiceConfig }

end.
MfG
schuetze09

FabienneCeline 10. Aug 2009 15:31

Re: Dienst-Management 4 dummies
 
@ schuetze09

Danke für deine Routinen. Konnte sie gut gebrauchen

Bin der Meinung, dass in 'function DoQueryServiceConfig' 'QueryServiceConfig(hService, PServiceConfig, BytesNeeded, BytesNeeded);' durch 'Result := QueryServiceConfig(hService, PServiceConfig, BytesNeeded, BytesNeeded);' ersetzt werden sollt. Sonst ist der Rückgabewert der function immer false (durch das einleitende Result:= false.

fabienne


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:42 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