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 ThreadMessages in Service (https://www.delphipraxis.net/162345-threadmessages-service.html)

slemke76 18. Aug 2011 11:05

ThreadMessages in Service
 
Hallo zusammen,

ich habe einen kleinen Dienst programmiert, der im ServiceStart drei Threads created und startet. Die Threads kommunizieren untereinander mit PostThreadMessage und GetMessage/PeekMessage. Klappt auch gut.
Jetzt möchte ich aber gerne dem Hauptprogramm aus einem Thread heraus eine Nachricht schicken, damit der zum Beispiel den gesamten Dienst beendet. Das habe ich folgendermassen angestellt:

Thread-Code:
Delphi-Quellcode:
New(InfoMessageRecord);
InfoMessageRecord^.ThreadID := GetCurrentThreadID;
InfoMessageRecord^.Content := 'Got critical error';
PostThreadMessage(fThreadIDs.Controller, CNTR_MESSAGING, CNTR_QUIT, 0);

// quick&dirty ;-)
// rum-Idlen bis der Thread beendet wird
while not Terminated do
  Sleep(1000);
Der Wert von fThreadIDs.Controller wird im Hauptprogramm / ServiceStart mit GetCurrentThreadID() bestimmt (vielleicht ist das bereits der Fehler).

Im Hauptprogramm sieht .ServiceExecute so aus:
Delphi-Quellcode:
  while not Terminated do begin
    doFileDebug('[MAIN] polling PeekMessage....');
    while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin

      doFileDebug('[MAIN] PeekMessage fired....');

      // bei WM_Quit immer raus.
      if (Msg.message = WM_QUIT) or
         ((Msg.message = CNTR_MESSAGING) and (Msg.wParam = CNTR_QUIT)) then begin
        // Irgendjemand sagt, er will beendet werden.
        doFileDebug('[MAIN] got Program quit message');
//        ServiceStopShutdown;
      end;
    end;
    // Keine Nachricht.
    // Schlafen legen und wieder von vorn ;-)
    Sleep(1000);
    ServiceThread.ProcessRequests(False);
  end;
doFileDebug ist Thread-Safe.

Die "[MAIN] polling PeekMessage.." kommt.
Wird jetzt aber im Thread "PostThreadMessage" ausgeführt, stürzt alles ab.

Wo ist mein Denkfehler?
Kann ich PostThreadMessage überhaupt verwenden ?
Ist GetCurrentThreadID() verkehrt?
Ich vermute, ich habe hier den falschen Ansatz - ein self.threadid gibt’s auch nicht habe ich gerade gesehen. Wie lässt sich die gewünschte Funktionalität sonst umsetzen ?

Danke,
Sebastian

Luckie 18. Aug 2011 11:17

AW: ThreadMessages in Service
 
Also zu deinem Fehler kann ich jetzt nichts sagen. Mir fällt aber was anderes auf: WM_QUIT. Was soll denn das? Wie die Präfix WM schon sagt handelt es sich da bei um eine WindowMessage, also einer Fensternachricht, die an Fenster verschickt wird. Ein Service hat aber kein Fenster. Er wird diese Nachricht also nie bekommen. Hinzukommt, dass Fensterhandle an den Desktop gebunden sind. Ein Service läuft aber in einer ganz anderen Windows Station auf einen ganz anderen Desktop. Fensternachrichten vom Desktop des Benutzers werden den Service also nie erreichen.

slemke76 18. Aug 2011 11:31

AW: ThreadMessages in Service
 
Hi !

WM_QUIT steht eigentlich nur der Vollständigkeit halber drin. Ein Fenster hat der Service natürlich nicht und es wird sonst auch nicht damit gearbeitet.
Ich bin gerade am rätseln, wie man das Problem löst. Offensichtlich ist mein Ansatz falsch. Es gibt weder ein self.threadid noch ein self.handle im Service-Kontext. Wie also spreche ich ihn vom Thread aus an ?

Grüße,
Sebastian

slemke76 18. Aug 2011 11:57

AW: ThreadMessages in Service
 
Hallo nochmal,

Antwort auf mich selber - auch schick 8-).
Ich habe es jetzt wie hier vorgeschlagen gelöst:
http://delphi.about.com/od/windowssh.../aa093003b.htm

Und über AllocateHWND ein "hidden window" erzeugt.
Klappt sehr gut.

Frage ist, ob das der empfohlene Weg ist, oder ob es einen anderen, sinnvolleren, gibt.

Sebastian


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