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 Windows Service Kommunikation (https://www.delphipraxis.net/196412-windows-service-kommunikation.html)

QuickAndDirty 18. Mai 2018 17:36

Windows Service Kommunikation
 
Man kann ja TService.DoCustomControl überschreiben
Delphi-Quellcode:
function TMyService.DoCustomControl(CtrlCode: DWord): Boolean;
begin
  //WinApi.SvcMgr.CM_SERVICE_CONTROL_CODE  für Postmessage
  //Erster message parameter größer Winapi.Winsvc.SERVICE_CONTROL_TRIGGEREVENT = $00000020
end;
Ich könnte den Service also eigene Controlcodes verarbeiten lassen.

Was mir noch etwas schleierhaft ist. Sende ich diese Codes direkt an ein ProcessHandle vom Service?
Sende ich diese codes per ServiceManager indirekt?


Müsste als Rückkanal der ServiceStatus dienen? Bzw. reagiert irgend etwas im Servicemanager ungut auf selbst erfundene Service-Statuswerte?

Ich möchte möglichst leichtgewichtig und direkt zwischen Dienst und Anwendung kommunizieren...

Ist das was ich da vorhabe "Böse und Schlecht"?

Mavarik 18. Mai 2018 17:39

AW: Windows Service Kommunikation
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1402480)
Ich möchte möglichst leichtgewichtig und direkt zwischen Dienst und Anwendung kommunizieren...

UDP?

Oder damit man nicht ein eigenes Protokoll bauen muss HTTP(s)?

Mavarik

PS.: Baue gerade selber so etwas... ;-)

QuickAndDirty 19. Mai 2018 23:39

AW: Windows Service Kommunikation
 
Udepe und hatetepe werden oft von Rechten und Admin policies berührt(Denke ich zumindest im Moment), deswegen wollte ich auf TCP und UDP und Soap verzichten.
Ich(oder rein Kollege) hatte mal nen Versuch mit Memory Maped Files
...das war auch nicht gerade zuverlässig
...scheinbar ist es möglich das MMF irgendwie blockiert wird.

Ich will auch nichts kompliziertes senden.
Ich will nicht viel Programmieren oder ein neues System entwickeln.
Eigentlich nur integers(Funktions nummern ohne Parameter und Antworten) austauchen.

Gibt es Admins die das Eventlog blockieren? Kann man das Eventlog blockieren?
Eventlog ist ja auch ne prima Semaphore und Pollbar. Und auch noch transparent.

Oder

Wie funktioniert das mit den CustomControlCodes?

KodeZwerg 20. Mai 2018 00:09

AW: Windows Service Kommunikation
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1402555)
Wie funktioniert das mit den CustomControlCodes?

So hier.....

Vorweg, mit DoCustomControl kann man nur einseitig etwas an den Service schicken
In diesem Beispiel gehe ich über eine vordefinierte Trigger-Liste TServiceControlCode um ans Ziel zu gelangen.

Das gehört in den Service
Delphi-Quellcode:
//Protected TMyService Deklaration überschreiben
function DoCustomControl(CtrlCode: DWord): Boolean; override;



// hier definiere ich Namen als Nummer, passe Namen an Deine Wunschtrigger an
type
  TServiceControlCode = (scRefreshProcesses, scUnused1, scUnused2, scUnused3, scUnused4, scUnused5, scUnused6, scUnused7);

function TNyService.DoCustomControl(CtrlCode: DWord): Boolean;
var
  ProcessKey, Command, I: Integer;
begin
  Result := True;
  I := CtrlCode and 127;
  ProcessKey := I shr 3;
  Command := I and 7; // die 7 muss zu der Menge der Trigger passen, bei 0 beginnend!
  if ProcessKey = 0 then
   begin
     case TServiceControlCode(Command) of
       scRefreshProcesses: begin end; // was soll passieren wenn scRefreshProcesses getriggert wurde?
     end;
   end;
end;
Das gehört in Applikation
Delphi-Quellcode:
// hier definiere ich Namen als Nummer, passe Namen an Deine Wunschtrigger an
type
  TServiceControlCode = (scRefreshProcesses, scUnused1, scUnused2, scUnused3, scUnused4, scUnused5, scUnused6, scUnused7);

function EncodeServiceControlCode(ProcessKey, ControlCode: Byte): DWord;
begin
  Result := 128 + ((ProcessKey and 15) shl 3) + (ControlCode and 7); // die 7 muss zu der Menge der Trigger passen, bei 0 beginnend!
end;

procedure SendServiceControlCode(ServiceHND: SC_HANDLE; ControlCode: DWord);
var
  ServiceStatus: TServiceStatus;
begin
  if Win32Check(QueryServiceStatus(ServiceHND, ServiceStatus)) then
   if (ServiceStatus.dwCurrentState and (SERVICE_STOPPED or SERVICE_STOP_PENDING)) = 0 then
    Win32Check(ControlService(ServiceHND, ControlCode, ServiceStatus))
  else RaiseLastOSError(GetLastError());
end;

function GetServiceHandle(const ComputerName, ServiceName: String): SC_HANDLE;
var
  SCManagerHND, ServiceHND: SC_HANDLE;
begin
  ServiceHND := := 0;
  SCManagerHND := OpenSCManager(PAnsiChar(ComputerName), nil, SC_MANAGER_ALL_ACCESS);
  if SCManagerHND <> 0 then
   begin
     ServiceHND := OpenService(SCManagerHND, PAnsiChar(ServiceName), SERVICE_QUERY_STATUS or SERVICE_USER_DEFINED_CONTROL);
   end;
   Result := ServiceHND;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // ersetze 'DeinServiceName' mit Deinem Service Namen
  // ersetze Ord(scRefreshProcesses) mit was auch immer du triggern möchtest
  SendServiceControlCode(GetServiceHandle('','DeinServiceName'), EncodeServiceControlCode(0, Ord(scRefreshProcesses)));
  // GetServiceHandle('','DeinServiceName') So = Lokal
  // GetServiceHandle('RemotePC','RemoteServiceName') So = Remote
end;
Weitere Hilfe zu diesem Thema
Das Ermitteln des Handle: OpenSCManager und OpenService
Das Senden: QueryServiceStatus und ControlService

Hilft Dir das weiter?


Zitat:

Zitat von QuickAndDirty (Beitrag 1402555)
Ich(oder rein Kollege) hatte mal nen Versuch mit Memory Maped Files
...das war auch nicht gerade zuverlässig
...scheinbar ist es möglich das MMF irgendwie blockiert wird.

IPC ist da eine schlechte Wahl, Service und Applikation laufen ja getrennt, Service sollte ja überall verfügbar sein aber Applikation ist auf Konto/Rechte gebunden. Es ist zwar Möglich aber mit mehr Aufwand als nötig.

QuickAndDirty 22. Mai 2018 09:48

AW: Windows Service Kommunikation
 
Super interessant! Ich teste es und gebe Bescheid.

Weist du ob ich für den Dienst eigene Status setzen kann ? Oder würdest du das Eventlog als besseren Rückkanal betrachten?

Der schöne Günther 22. Mai 2018 09:57

AW: Windows Service Kommunikation
 
Mir hat reine HTTP-Kommunikation zwischen Dienst und Client-Anwendung(en) immer gereicht.

Geht out of the box, super einfach und lässt sich ohne Aufwand debuggen.

(https://www.delphipraxis.net/184570-...erstellen.html)

KodeZwerg 22. Mai 2018 16:49

AW: Windows Service Kommunikation
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1402662)
Weist du ob ich für den Dienst eigene Status setzen kann ?

Eigener Status wäre nur so etwas Möglich: Dienst läuft, Dienst läuft nicht, das wars auch schon. Meintest das?
Zitat:

Zitat von QuickAndDirty (Beitrag 1402662)
Oder würdest du das Eventlog als besseren Rückkanal betrachten?

Erzähl mal mehr über was für eine Funktionalität es Dir tatsächlich geht.
Mein Beispiel bezog sich auf deine Fragen wie man einen Service Triggern kann. Service und Applikation sollte kein Chatprogramm sein oder Service ist vielleicht das falsche Mittel?
Einen Rückkanal kenne ich so bis jetzt noch nicht, da wird HTTP(s) vielleicht die bessere Methode sein aber ich selbst habe mit Service/Https <-> Applikation/Https Kommunikation keine Erfahrung, da halte Dich an Der schöne Günther.

KodeZwerg 22. Mai 2018 18:24

AW: Windows Service Kommunikation
 
SvCom da findest du eine kommerzielle Service Komponente.
Schau Dir mal die Beschreibungen an, wenn das was Du willst nicht dabei ist, dann vergiss normale Service Methoden und nutze die Http Variante.


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