ShellExecuteEx() warte bis FindWindow()

Thomasio

Erfahrenes Mitglied
Wenn ich mit ShellExecuteEx() eine .exe (Win32 Anwendung) starte und warte, bis deren MessageLoop läuft, müsste ich doch eigentlich gleich danach mit FindWindow() prüfen können, ob das Fenster vorhanden ist, oder nicht?

Code:
SHELLEXECUTEINFO ExecInfo = {0};
ExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ExecInfo.hwnd = 0;
ExecInfo.lpVerb = "open";
ExecInfo.lpFile = "MyProgram.exe;
ExecInfo.lpParameters = "";
ExecInfo.nShow = SW_SHOWNORMAL;
if(!ShellExecuteEx(&ExecInfo))
  {
       MessageBox(0,"MyProgram.exe nicht gefunden","ERROR",MB_OK);
  }
WaitForInputIdle(ExecInfo.hProcess,INFINITE);

if(!FindWindow("MyProgramClassName",0));
  {
       MessageBox(0,"Fenster nicht gefunden","ERROR",MB_OK);
  }

Wenn ich das so starte, bekomme ich immer "Fenster nicht gefunden".
Erst wenn ich zwischen Wait und Find ein Sleep(1000) einbaue funktioniert alles wie es soll.
Daraus schliesse ich erstmal, dass ich im Prinzip keinen Fehler drin habe, denn sonst würde es mit Sleep() auch nicht funktionieren.

Ich habe das 100 Mal überprüft, CreateWindow() und ShowWindow() steht in MyProgram.exe VOR dem MessageLoop, darum verstehe ich nicht, warum FindWindow() nur nach zusätzlichem Sleep() funktioniert, sollte der WaitForInputIdle() nicht reichen?

WENN Wait allein nicht reicht, gibt es eine andere Möglichkeit als das Ganze auf Verdacht eine bestimmte Zeit schlafen zu legen?
 
Hi,

du könntest eine Schleife machen, in dieser 100ms warten und das Fenster suchen. Somit wartet das Programm nicht länger als nötig. Hier müsstest du halt dann auch noch mitzählen wie oft du die Schleife bereits durchlaufen hast, dass bei einem Absturz des anderen Programms während des 100ms-Sleeps keine Endlosschleife entsteht.

Ich denke mal, dass das andere Programm seine Zeit braucht, um das Fenster zu erstellen. Seien es auch nur 100 ms, zu dem Zeitpunkt wie du dein FindWindow() machst ist er halt noch nicht fertig.

Gruß
BK
 
Ob 10x 100ms oder 1x 1000ms, das macht nicht den tollen Unterschied, geht im Zweifelsfalle etwas schneller, aber löst das Problem nicht, auf meinem I7-QuadCore mag 100ms reichen, aber was wenn das Programm irgendwann bei einem User auf einem alten lahmen PC laufen soll? Da reicht 1000ms vielleicht immer noch nicht und dann kann ich über den Daumen gepeilt raten, wie lange ist lange genug?

Die Frage ist, warum ist das Fenster nicht fertig?
Wenn CreateWindow() vorm MessageLoop aufgerufen wird, und ShellExecuteEx() wartet bis der MessageLoop läuft, wie kann es dann sein, dass der MessageLoop läuft, aber das Fenster noch nicht existiert?
Wozu soll die Wait-Funktion auf den MessageLoop überhaupt gut sein, wenn ich danach sowieso noch einen Sleep() einbauen muss, bevor ich dem Fenster via FindWindow() eine Message schicken kann?
Es macht doch keinen Sinn, ein laufendender MessageLoop in einem Fenster, was nicht gefunden werden kann.
 
Ein MessageLoop hat nicht direkt was mit einem Fenster zu tun. Ein Message Queue wird in einem Thread angelegt, sobald darin ein SendMessage/PostMessage aufgerufen wird. Es gibt auch Messages ohne Window. D.h. die Queue kann schon existieren, dein Fenster aber noch nicht.
Wenn du ganz sicher gehen willst, und auch den Code vom aufgerufenen Programm hast, würde ich das über eine Benachrichtigung vom aufgerufenen zum Aufrufer zurück machen. Du kannst ja als Aufrufparameter dein Lieblings-HWND mitgeben.
 
Zurück