![]() |
CreateProcess und anschließend WM_COPYDATA
Ich hoffe dass ich hier richtig bin.
Ich starte aus einem Programm heraus mit CreateProcess ein anderes Programm. Wenn der Handle da ist, übergebe ich mit WM_CopyDATA einen String. Das neu gestartete Programm empfängt den String und tut so manche Dinge damit. Mein Problem ist, dass wenn der Handle schon vorhanden ist, ist das neu aufgerufene Programm noch nicht in der Lage den zu empfangenden String entgegenzunehmen. Also mein SendMessage geht an dem gestarteten Programm vorbei (kommt nicht an). Wenn ich nun, nachdem das andere Programm gestartet ist nochmals den SendMessage mache, dann funktionierts.
Delphi-Quellcode:
Wo mache ich den Denkfehler?
procedure TFormMain.KindProgrammClick(Sender: TObject);
var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; s : string; h : HWND; cds : TCopyDataStruct; n : integer; begin FillChar(StartupInfo, SizeOf(TStartupInfo), 0); StartupInfo.cb := Sizeof(TStartupInfo); if CreateProcess(nil, { Anwendungsname} 'KindProgramm.exe', { Parameter} nil, { Security} nil, { Security} False, NORMAL_PRIORITY_CLASS, { Priorität} nil, { Environment} {PVerzeichnis,} { Verzeichnis} 'C:\MeinOrdner', { Verzeichnis} StartupInfo, ProcessInfo) then begin h:=FindWindow(nil,Pchar('KindProgramm')); end else Showmessage('Fehler! Programm KindProgramm.EXE ins Verzeichnis C:\MeinOrdner !'); h:=FindWindow(nil,Pchar('KindProgramm.exe')); repeat //Warten bis Empfänger geöffnet und empfangsbereit ist h:=FindWindow(nil,PChar('KindProgramm')); StatusBar1.SimpleText:='Bitte warten!!!'; until h<>0; begin // Empfänger-Fenster gefunden -> Daten senden cds.dwData:=0; cds.cbData:=StrLen(PChar(s)); //Length(s); cds.lpData:=PChar(s); SendMessage(h,WM_COPYDATA,Longint(Handle),Longint(@cds)); //<- kommt nicht an, erst beim zweiten Aufruf end; end; |
Re: CreateProcess und anschließend WM_COPYDATA
Du hast hier wahrscheinlich Laufzeitprobleme. Die MEssagequeue ist evtl. nocht nicht fertig angelegt etc. pp.
Warum übergibst du das nicht direct bei CreateProcess im Parameter? |
Re: CreateProcess und anschließend WM_COPYDATA
Hallo sirius,
gibt es eine Möglichkeit die Laufzeitprobs in den Griff zu bekommen? Ich übergebe es nicht per Parameter, weil wenn ich im Vaterprogramm eine Eingabe mache, muss das Kindprogramm das übergeben bekommen.. Per Parameter wäre ja nur beim Öffnen einmalig.... oder? |
Re: CreateProcess und anschließend WM_COPYDATA
Dann übergib im Parameter das Handle o.ä. eines deiner Fenster. Und wenn dein Kindprogramm fertig ist mit dem Aufbau, schickt es eine "Hallo da bin ich Message" mit den Absenderdaten an dein Programm. Und dann kannst du die Absenderdaten dazu nutzen dein eigenes Zeugs zu versenden.
Damit entfällt das mühselige Findwindow. |
Re: CreateProcess und anschließend WM_COPYDATA
Du kannst
![]() |
Re: CreateProcess und anschließend WM_COPYDATA
@ Apollonius
WaitForInputIdle hab ich probiert. Sehr seltsam das verhalten, kann man kaum in Worte fassen... Ich versuchs mal.
Delphi-Quellcode:
dann kommt der Sendmessage-Part im Listing.h:=FindWindow(nil,'KindProgramm'); repeat //Warten bis Empfänger geöffnet und empfangsbereit ist h:=FindWindow(nil,'KindProgramm'); StatusBar1.SimpleText:='Bitte warten!!!'; until h<>0; StatusBar1.SimpleText:='gefunden, warten bis eingabebereit ist'; xc:=WaitForInputIdle(h,300000); //30Sec showmessage(intToStr(xc)); Was passiert an der Oberfläche -> 'Bitte warten' kommt als erstes in die StatusBar, dann kommt 'gefunden, warten bis eingabebereit ist' dann vergehen 30Sec. Vom Kindprogramm ist bis dahin nix zu sehen. 30sec lang... tze Nach 30 sec kommt das Kindprogi vor das Vaterprogi. Dann kommt das Showmessage mit der Zahl '4GB' in dezimal, logo. Das klicke ich weg, dann kommt die SendMessage, die am Kindprogi wieder vorbei geht. Ich blicks bald gar nimmer.... @ sirius Das werde ich jetzt mal tun: Im Kindprogi mal zurückübergeben, dann im Vaterprogi auswerten. Ist vielleicht ganz geschickt, denn dann kann ich Status auch hin und her schieben... |
Re: CreateProcess und anschließend WM_COPYDATA
Wie wäre es damit?
Delphi-Quellcode:
procedure TFormMain.KindProgrammClick(Sender: TObject);
var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; s : string; h : HWND; cds : TCopyDataStruct; n : integer; begin FillChar(StartupInfo, SizeOf(TStartupInfo), 0); StartupInfo.cb := Sizeof(TStartupInfo); if CreateProcess(nil, { Anwendungsname} 'KindProgramm.exe', { Parameter} nil, { Security} nil, { Security} False, NORMAL_PRIORITY_CLASS, { Priorität} nil, { Environment} {PVerzeichnis,} { Verzeichnis} 'C:\MeinOrdner', { Verzeichnis} StartupInfo, ProcessInfo) then begin StatusBar1.SimpleText:='Bitte warten!!!'; WaitForInputIdle(ProcessInfo.hProcess, INFINITE); ... |
Re: CreateProcess und anschließend WM_COPYDATA
Vielen Dank @Garfield,
Das Zitat:
Hab das jetzt so stehen:
Delphi-Quellcode:
Das habe ich nun ein paar mal getestet und das funktioniert soweit.
procedure TFormMain.KindProgrammClick(Sender: TObject);
var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; s : string; xc : cardinal; h : THandle; //h : HWND; cds : TCopyDataStruct; begin FillChar(StartupInfo, SizeOf(TStartupInfo), 0); StartupInfo.cb := Sizeof(TStartupInfo); //StrPCopy(PVerzeichnis,LW_Char+':\MeinOrdner'); if CreateProcess(nil, { Anwendungsname} 'KindProgramm.exe', { Parameter} nil, { Security} nil, { Security} False, NORMAL_PRIORITY_CLASS, { Priorität} nil, { Environment} {PVerzeichnis,} { Verzeichnis} 'MeinOrdner', { Verzeichnis} StartupInfo, ProcessInfo) then begin //showmessage ('Gestartet'); end else Showmessage('Fehler! Programm KindProgramm.EXE ins Verzeichnis C:\MeinOrdner !'); StatusBar1.SimpleText:='gefunden, warten bis eingabebereit ist'; WaitForInputIdle(ProcessInfo.hProcess, INFINITE); repeat //Warten bis Empfänger geöffnet und empfangsbereit ist h:=FindWindow(nil,'KindProgramm'); StatusBar1.SimpleText:='Bitte warten!!!'; until h<>0; cds.dwData:=0; cds.cbData:=Length(s); cds.lpData:=PChar(s); SendMessage(h,WM_COPYDATA,integer(H),integer(@cds)); xc:=GetlastError; if xc<>0 then begin SendMessage(h,WM_COPYDATA,integer(H),integer(@cds)); end; end; end; Aber ich denke die Lösung ist quick and dirty. Den Denkfehler den ich mache hab ich nur umgangen, aber nicht behoben oder? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:20 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