Manchmal gibts keinen handle... :-(



  • Hallo,

    folgende Situation:

    Ich schreibe ein Programm mit dem ich ein anderes steuern möchte und zwar über Tastendrücke. Realisiert habe ich das in etwa so:

    ShellExecute(0,NULL,"C:\\windows\\system32\\notepad.exe",NULL,NULL,SW_SHOWMAXIMIZED);
    HWND EDIT = FindWindow(NULL, "Unbenannt - Editor");
    

    Dann bekomme ich in der Regel den handle, setze die Anwendung mit SetForegroundWindow(EDIT) nach vorn und kann anfangen mit keybd_event Tastendrücke an den Editor zu senden. Danach nehm ich den handle von meinem Progamm und hol das dann wieder in den Vordergrund um weiter zu machen. Alles wunderbar.

    Das klappt auch mit anderen Programmen Word, FlashPlayer usw...

    Aber manchmal geht beim ersten Versuch nach dem Starten von Windows (Programm wird über Verknüpfung im Autostart mitgestartet) gar nix. Ich bekomme als handle "NULL" zurück und bekomm das Programm also nicht zu greifen um ihm irgendwelche Tasten zu schicken. Beende ich mein Programm, rufe es anschließend erneut auf, klappt alles wie gehabt. Starte ich neu, klappts beim ersten Anlauf meist wieder nicht.

    Das ist echt verzwickt, vor allem weil es halt nur "manchmal" ist. Ich habe es auch schon versucht, dass ich zwischen ShellExecute und FindWindow mit Sleep mal ne Sekunde warte, aber auch das nutzt nix. Habe vermutet, dass der aufgerufene Prozess noch nicht vollständig erstellt wurde und deshalb kein handle zurückkommt.

    Mit ShellExecuteEx klappt gar nix. Das gibt ja kein handle sondern hinstance zurück und damit komm ich nicht wirklich zurecht.

    Auch wenn ich mit CreateProcess das externe Programm aufrufe komm ich nicht weiter. Beide handles hThread und hProcess aus der ProcessInformation struct unterscheiden sich von dem handle, welchen ich mit FindWindow bekomme. Und klappen tuts mit beiden nicht.

    Kurz:
    Woran kann es liegen, wenn ich keinen handle bekomme?
    Irgendwelche Ideen zu erzwingen, dass ich den handle korrekt bekomme (z.B. doch irgendwie mit CreateProcess)?

    thx



  • Woran kann es liegen, wenn ich keinen handle bekomme?

    Nach dem ShellExecute Aufruf ist es eine Frage der Zeit bis das Handle gültig wird... bzw. das Programm wirklich gestartet ist...

    Simon



  • Aber manchmal geht beim ersten Versuch nach dem Starten von Windows (Programm wird über Verknüpfung im Autostart mitgestartet) gar nix

    Kann es sein, das du manchmal versuchst das Handle zu früh zu bekommen, bevor das andere Programm richtig gestartet ist?



  • hm, genau das hab ich mir auch gedacht und zwischen dem ShellExecute und dem FindWindow ein Sleep(1000) eingebaut. Laufen tut das Ganze auf nem 2 GHz Dual Core mit 2GB Ram und WinXP, dachte das sollte reichen. Aber auch so tritt das Problem ab und an auf.



  • WaitForInputIdle

    ...
    For example, the parent process should use WaitForInputIdle before trying to find a window associated with the child process.


  • Mod

    Dennoch sollte man in diesem Fall ShellExecuteEx verwenden. Man hat dann ein Prozesshandle und kann auch gezielt nach Fenstern des Prozesses suchen.



  • okay, ich habe mal ein beispiel von
    http://www.codeguru.com/forum/showthread.php?t=302501
    genommen und folgendes probiert:

    SHELLEXECUTEINFO ExecuteInfo;
    
    	memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));
    
    	ExecuteInfo.cbSize       = sizeof(ExecuteInfo);
    	ExecuteInfo.fMask        = 0;
    	ExecuteInfo.hwnd         = 0;
    	ExecuteInfo.lpVerb       = "open";
    	ExecuteInfo.lpFile       = "C:\\windows\\notepad.exe";
    	ExecuteInfo.lpParameters = 0;
    	ExecuteInfo.lpDirectory  = 0;
    	ExecuteInfo.nShow        = SW_SHOW;
    	ExecuteInfo.hInstApp     = 0;
    
    	ShellExecuteEx(&ExecuteInfo);
    
    	HWND ExInfo_handle = ExecuteInfo.hwnd;
    	HWND FWin_handle = FindWindow(NULL, "Unbenannt - Editor");
    

    Der Editor öffnet sich, aber:
    in ExInfo_handle steht "NULL" und in FWin_handle etwas ungleich "NULL" und mit diesem handle kann ich den Editor auch ansprechen mit ExInfo_handle nicht.

    Vermute ich richtig, dass

    ExecuteInfo.hwnd         = 0;
    

    nur ein Initialisierungswert ist? Erwartet wird ja ein void.

    Ich hab das Gefühl irgendwie auf der Leitung zu sitzen 😞



  • So, das WaitForInputIdle hab ich mir auch mal angeschaut:

    DWORD WINAPI WaitForInputIdle(
      __in  HANDLE hProcess,
      __in  DWORD dwMilliseconds
    );
    

    ... brauche also dafür auch schon den entsprechenden handle! 😞



  • Martin Richter schrieb:

    Dennoch sollte man in diesem Fall ShellExecuteEx verwenden. Man hat dann ein Prozesshandle


Anmelden zum Antworten