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 CreateProcess in thread mit eigener messageloop? (https://www.delphipraxis.net/178111-createprocess-thread-mit-eigener-messageloop.html)

Memnarch 18. Dez 2013 09:08

CreateProcess in thread mit eigener messageloop?
 
Moin allerseits,
Ich habe folgendes Problem:

per CreateProcess starte ich ein Programm, wie z.B. powershell(v1) mit einem gegebenen script. Im Startupinfo record gebe ich sw_hide an, damit die Konsole der Powershell nicht angezeigt wird.

Wenn dass das einzige ist, was ich mache klappt alles wunderbar. Wird z.B. im Powershell-Script ein Dialog angezeigt, funktioniert dieser tadellos.

Wenn ich aber blockierend auf das beenden des Prozesses warte, dann geht das nicht mehr. Warum? Durch SW_Hide bin ich aus irgendeinem Grund jetzt plötzlich für die abarbeitung der messages zuständig. Warte ich blockierend werden natürlich keine messages abgearbeitet und die Dialoge aus Powershell gehen nicht.Im gegensatz dazu: Per SW_Show erstellt die Powershell ihr hauptfenster und mein Prozess darf blockend warten, wärend alles weitere ohne Probleme funktioniert.

Ich möchte aber auch nicht, das grundsätzlich Nachrichten(wie die für VCL) abgearbeitet werden(i.e. Application.processmessages).

Meine Idee wäre dann gewesen, CreateProcess in einem anderen Thread auszuführen, der praktisch dann die Arbeit zugesprochen bekommt und der Hauptthread kann blockend warten.

Bisher war dies aber nicht von Erfolg gekrönt. Ich habe es per unsichtbarem Fenter im Thread als auch generel per pek/translate/dispatchmessage vor und danach(in einer loop) versucht, um die Messagequeue im Thread zu erstellen und am leben zu erhalten. Allerdings wählt sich Windows/Createprocess immer die Hauptqueue aus. Solange da kein Application.ProcessMessages im Hauptthread steht, läuft da nichts mit Dialogen.

Ich möchte vorzugsweise CreateProcess nutzen, um STDIN/Out/Err auswerten/nutzen zu können.

Hat jemand eine Ahnung, was hierbei die Ursache sein könnte?

EDIT: interressanter Nebeneffekt: Beende ich meien Applikation und die Powershelll bleibt am leben, so funktioniert danach der Dialog. anscheinend übernimmt die Powershell dann wieder die Arbeit?

Grüße
Memnarch

samso 18. Dez 2013 09:26

AW: CreateProcess in thread mit eigener messageloop?
 
CREATE_NEW_CONSOLE ist gesetzt? Möglicherweise hilft auch "AttachThreadInput" weiter(?)

Memnarch 18. Dez 2013 09:44

AW: CreateProcess in thread mit eigener messageloop?
 
1) Ja ist gesetzt
2) nein hilft leider nicht :(

edit: ok attachthreadinput hat nicht funktioniert. ENtweder habe ich oder der neue prozess keine messageloop...

edit2: ok habe inzwischen den threadinput verbinden können, aber es hat sich nichts geändert :(

samso 18. Dez 2013 10:44

AW: CreateProcess in thread mit eigener messageloop?
 
Also, falls Du ein Demoprogramm für mich hättest, würde ich mich an der Fehlersuche beteiligen. Gibt es den Fehler auch, wenn Du die Umleitung der StdIn/Out nicht machst?

Memnarch 18. Dez 2013 11:30

AW: CreateProcess in thread mit eigener messageloop?
 
Jup diesen "Fehler"(Anführungszeichen, weiß ich nicht wie ich es einordnen soll) gibts auch dann.

Ich kann aktuell keine Demo zur Verfügung stellen(gucke was sich da machen lässt). Aber für die reproduktion die nötigsten Infos(falls wer die Zeit hat):

sw_hide im StartupInfo record setzen

CreateProcess mit folgenden Parametern(alles andere nil oder 0):

ApplicationName = pfad zur Powershell.exe
CommandLine = -File euerscript.ps1
InheritesHandles = True

StartupInformation übergeben die ihr vorher gesetzt habt
und natürlich die Referenz zum ProcessInformation record

Sofern das startet, danach einfach waitforsingleobject oder anderweitig blockend(!) auf das beenden dieses Prozesses warten.

In eurem Powershell script müsst ihr dann nur noch etwas ausführen, dass einen Dialog anzeigt.
get_credentials z.B. fragt den nutzer nach ebend diesen ab.

PS: gerade gemerkt, das anscheinend nur get_credentials dieses Problem haben könnte. eine normale messagebox, wie sie im folgenden Link beschrieben wird, funktioniert einwandfrei...?!
http://powershell-tips.blogspot.de/2...owershell.html

edit2: ok ne messagebox ist wohl auch nen fall für sich. DIe pumpt von selbst die Messageloop.

Memnarch 18. Dez 2013 15:03

AW: CreateProcess in thread mit eigener messageloop?
 
Ok, notgedrungen halte ich halt jetzt die MessageLoop einfach weiter am leben, wärend der Prozess noch läuft und ich warte. Geht vorerst halt nicht anders.

Aktuell habe ich aber noch das Problem, dass nach dem beenden des Scriptes sich die Powershell nicht beendet, wenn ich den Output weiterleite... :(

EDIT: ok lag daran, dass meine klasse auch den STDIn angebunden hat. Das signalisiert der Powershell wohl bereitschaft und sie wartet.

himitsu 18. Dez 2013 15:28

AW: CreateProcess in thread mit eigener messageloop?
 
Hatte mich schon gewundert, denn eigentlich sind die MessageQueues ja an den Thread gebunden, in welchem die GUI-Komponenten erstellt wurden (CreateWindow).
Und somit hat jede Anwendung ihre eigene Queue. (abgesehn von z.B. ConsolenApps, welche kein GUI verwenden)

Memnarch 19. Dez 2013 15:25

AW: CreateProcess in thread mit eigener messageloop?
 
@Himitsu: ich wunder mich noch immer, den abarbeiten muss ich das Ding immernoch selber. Oder irgendwas anderes sorgt für diesen nebeneffekt(Dieser credential-dialog wird auch praktisch modal gegenüber dem Hauptfenster!...aber nicht anderen modalen fenstern, die ich schon habe o.O)

Memnarch 20. Dez 2013 10:04

AW: CreateProcess in thread mit eigener messageloop?
 
Ok, Ok, ich muss die Segel streichen. Ich muss die Console einfach anzeigen, ansonsten klappt irgendwas irgendwie nicht bei visuellen Dialogen :(.

Wenn ich es in WScript einbette, dann geht zumindest der Credentials dialog, nicht aber normale Forms. Der grund ist, das alle weiteren Forms mit dem selben SW_-Status erstellt werden. Das ist supoptimal.

Was ich bräuchte wäre eine methodik, um einen Prozess mit gegebenen Startupinfos mit SW_HIDE zu erstellen, und danach dem Prozess mit zu teilen, dass SW_Default nicht SW_HIDE sondern z.B. SW_SHow ist. StartupInformation lässt sich ja nicht nachträglich ändern.

Was ich auch machen kann, ist verzögerte ausführung. Also powershell starten [irgendwas machen] dann mein Script ausführen. Wen man innerhalb der Powershell(da man ja im eigenen Prozess ist) diese werte ändern könnte, wäre das so möglich.

Jemand ne Idee?


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