AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

CreateProcess und anschließend WM_COPYDATA

Offene Frage von "hirsch"
Ein Thema von hirsch · begonnen am 4. Mär 2009 · letzter Beitrag vom 5. Mär 2009
Antwort Antwort
hirsch

Registriert seit: 29. Jan 2008
Ort: Tuttlingen
88 Beiträge
 
Delphi 2007 Professional
 
#1

CreateProcess und anschließend WM_COPYDATA

  Alt 4. Mär 2009, 16:45
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:
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;
Wo mache ich den Denkfehler?
Wolfgang Hirsch
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 4. Mär 2009, 16:59
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?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
hirsch

Registriert seit: 29. Jan 2008
Ort: Tuttlingen
88 Beiträge
 
Delphi 2007 Professional
 
#3

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 4. Mär 2009, 17:15
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?
Wolfgang Hirsch
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 4. Mär 2009, 17:18
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.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 4. Mär 2009, 18:05
Du kannst MSDN-Library durchsuchenWaitForInputIdle verwenden, um auf das Ende der Initialisierung zu warten.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
hirsch

Registriert seit: 29. Jan 2008
Ort: Tuttlingen
88 Beiträge
 
Delphi 2007 Professional
 
#6

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 5. Mär 2009, 09:41
@ Apollonius
WaitForInputIdle hab ich probiert.
Sehr seltsam das verhalten, kann man kaum in Worte fassen...
Ich versuchs mal.
Delphi-Quellcode:
     
     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));
dann kommt der Sendmessage-Part im Listing.

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...
Wolfgang Hirsch
  Mit Zitat antworten Zitat
Benutzerbild von Garfield
Garfield

Registriert seit: 9. Jul 2004
Ort: Aken (Anhalt-Bitterfeld)
1.335 Beiträge
 
Delphi XE5 Professional
 
#7

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 5. Mär 2009, 12:18
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);
       ...
Gruss Garfield
Ubuntu 22.04: Laz2.2.2/FPC3.2.2 - VirtBox6.1+W10: D7PE, DXE5Prof
  Mit Zitat antworten Zitat
hirsch

Registriert seit: 29. Jan 2008
Ort: Tuttlingen
88 Beiträge
 
Delphi 2007 Professional
 
#8

Re: CreateProcess und anschließend WM_COPYDATA

  Alt 5. Mär 2009, 13:46
Vielen Dank @Garfield,
Das
Zitat:
WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
habe ich eingefügt, hat aber nix gebracht oder verändert.
Hab das jetzt so stehen:
Delphi-Quellcode:
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;
Das habe ich nun ein paar mal getestet und das funktioniert soweit.
Aber ich denke die Lösung ist quick and dirty.
Den Denkfehler den ich mache hab ich nur umgangen, aber nicht behoben oder?
Wolfgang Hirsch
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:04 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