![]() |
RunAndWaitShell - FindWindowEx Konflikt ?!?
Ich hab ein Problem. Folgenden Code nehme ich als Fix her für ein Programm das ich von meinem Tool aus starte. Eine der neueren Versionen blockiert mein Tool wärend es läuft. Gedacht war es, das ich Zugriff auf beide Programme haben. Ich kann von meinem Tool aus den kompletten Vorgang abbrechen. Das geht nur nicht, wenn es einfriert.
Das Einfrieren meines Tools hatte ich schon. Gelöst wurde es mit RunAndWaitShell. Wenn ich nun bei der neuen Version des Programms was ich fernsteuere manuel den Knopf drücke (sprich per Maus) ist mein Programm nicht blockiert (eingefrohren). Sobald ichs aber per Code mache frierts wieder ein. Ich hab mehrere Varianten ausprobiert (siehe //), komme aber nicht auf den grünen Zweig. Was kann es sein, das es doch einfriert?
Delphi-Quellcode:
Hier nochmal RunAndWaitShell:
procedure TForm1.EncodefixtimerPredTimer(Sender: TObject);
var Key: Char; wnd2: hWnd; pfad:string; begin EncodefixtimerPred.Enabled:=false; pfad := ExtractFilePath(ParamStr(0)) ; wnd2 := FindWindow('#32770', PChar(Fenstertitel.text)); wnd2 := FindWindowEx(wnd2, 0, 'Button', 'Knopf'); //if wnd2=0 then exit else if wnd2 <> 0 then begin SendMessage(wnd2,BM_CLICK,0,0); //wnd2:=0; end; end;
Delphi-Quellcode:
procedure RunAndWaitShell(Executable, Parameter: STRING; ShowParameter: INTEGER);
var Info: TShellExecuteInfo; pInfo: PShellExecuteInfo; exitCode: DWord; begin {Pointer to Info} pInfo := @Info; {Fill info} with Info do begin cbSize := SizeOf(Info); fMask := SEE_MASK_NOCLOSEPROCESS; wnd := application.Handle; lpVerb := NIL; lpFile := PChar(Executable); {Parametros al ejecutable} {Executable parameters} lpParameters := PChar(Parameter + #0); lpDirectory := NIL; nShow := ShowParameter; hInstApp := 0; end; {Execute} ShellExecuteEx(pInfo); {Wait to finish} repeat exitCode := WaitForSingleObject(Info.hProcess, 500); Application.ProcessMessages; until (exitCode <> WAIT_TIMEOUT); end; |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Moin Amnon,
das erste was mir auffällt (eventuell soll das aber auch so sein): Du schaltest den Timer ab, schaltest ihn am Ende der OnTimer Prozedur aber nicht wieder ein. Bist Du schon einmal im Einzelschritt durch die OnTimer-Prozedur gegangen, und hast die Werte geprüft? |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Noch nicht. Was ich vergessen hab zu sagen ist folgendes. Der Fenstertitel verschwindet dann, wenn man auf den Knopf gedrückt hat. Anscheinend läuft der Timer weiter, was ich mir aber nicht erklären kann, da ich ihn abgeschalten hatte. Ich prüfe nun die Werte und sag Dir bescheid.
|
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Moin Amnon,
Du solltest auch das erste Handle auf Gültigkeit prüfen. |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Der Code für den Test:
Delphi-Quellcode:
Hier die Werte von dem Test mit der neuen Version des Programms, wo mein Tool einfriert:
procedure TForm1.EncodefixtimerPredTimer(Sender: TObject);
var Key: Char; wnd2: hWnd; pfad:string; begin memo1.lines.add(TimeToStr(time)+' '+'timer start'); memo1.lines.add(TimeToStr(time)+' '+'##################'); pfad := ExtractFilePath(ParamStr(0)) ; wnd2 := FindWindow('#32770', PChar(Fenstertitel.text)); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); wnd2 := FindWindowEx(wnd2, 0, 'Button', 'Knopf'); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); //if wnd2=0 then exit else if wnd2 <> 0 then begin SendMessage(wnd2,BM_CLICK,0,0); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); //wnd2:=0; end; memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); EncodefixtimerPred.Enabled:=false; memo1.lines.add(TimeToStr(time)+' timer end'); memo1.lines.add(TimeToStr(time)+' ##################'); end;
Code:
Den dritten Durchlauf hab ich abgebrochen ...
15:11:12timer start
15:11:12 ################## 15:11:12 460776 15:11:12 460770 15:12:32 460770 15:12:32 460770 15:12:32 timer end 15:12:32 ################## 15:12:35 timer start 15:12:35 ################## 15:12:35 526306 15:12:35 526294 15:13:55 526294 15:13:55 526294 15:13:55 timer end 15:13:55 ################## 15:13:58 timer start 15:13:58 ################## 15:13:58 0 15:13:58 0 15:13:58 0 15:13:58 timer end 15:13:58 ################## Hier nun die Werte mit einer älteren Version des Programms wo's nicht einfriert:
Code:
Auch hier hab ich den dritten Durchlauf abgebrochen ...
15:18:59 timer start
15:18:59 ################## 15:18:59 0 15:18:59 0 15:18:59 0 15:18:59 timer end 15:18:59 ################## 15:20:21 timer start 15:20:21 ################## 15:20:21 0 15:20:21 0 15:20:21 0 15:20:21 timer end 15:20:21 ################## 15:21:41 timer start 15:21:41 ################## 15:21:41 0 15:21:41 0 15:21:41 0 15:21:41 timer end 15:21:41 ################## Und hier hab ich mal den Timer bei einem Durchlauf mit dem neuen Programm nicht ausgeschaltet:
Code:
Nun die Schlussfolgerung. Beide Programme werden wie folgt gestartet:
15:32:18 timer start
15:32:18 ################## 15:32:18 1116130 15:32:18 657224 15:33:37 657224 15:33:37 657224 15:33:37 timer end 15:33:37 ################## 15:33:37 timer start 15:33:37 ################## 15:33:37 0 15:33:37 0 15:33:37 0 15:33:37 timer end 15:33:37 ################## 15:33:39 timer start < Zeiter Durchlauf > 15:33:39 ################## 15:33:39 0 15:33:39 0 15:33:39 0 15:33:39 timer end 15:33:39 ##################
Delphi-Quellcode:
Das alte Programm braucht den Knopfdrück-Fix nicht und startet sofort. Das neue hat einen Bug. Startet zwar aber fängt nicht an zu arbeiten. Wenn ich manuell auf den Knopf drücke fängt es an zu arbeiten. Mit dem Timer wollte ich das beheben. Sobald der Timer aber anspringt friert mein Hauptprogramm ein. Kann man dagegen was tun oder muss ich das so hinnehmen. Der Code erfüllt ja seinen Zweck ...
RunAndWaitShell(pchar(ProgrammpfaduEXE.txt), ' -par1 "'+path+'temp\datei1.endung" -batch',value);
Zu der Handle-Prüfung ... Wie stellt man das an? |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Ich hab nochwas ausprobiert, aber auch ohne Erfolg:
Delphi-Quellcode:
procedure TForm1.EncodefixtimerPredTimer(Sender: TObject);
var Key: Char; wnd2,wnd3: hWnd; pfad:string; begin memo1.lines.add(TimeToStr(time)+' '+'timer start'); memo1.lines.add(TimeToStr(time)+' '+'##################'); pfad := ExtractFilePath(ParamStr(0)) ; wnd2 := FindWindow('#32770', PChar(Fenstertitel.text); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); wnd3 := FindWindowEx(wnd2, 0, 'Button', 'Knopf'); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd3)); //if wnd2=0 then exit else if wnd3 <> 0 then begin SendMessage(wnd3,BM_CLICK,0,0); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd3)); //wnd2:=0; end; memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd3)); EncodefixtimerPred.Enabled:=false; memo1.lines.add(TimeToStr(time)+' timer end'); memo1.lines.add(TimeToStr(time)+' ##################'); end;
Code:
Ich hab den Code mit X-Spy generiert. Hier der Code von X-Spy:
15:56:24 timer start
15:56:24 ################## 15:56:24 wnd2 1247346 15:56:24 wnd2 1247346 15:56:24 wnd3 1575014 15:57:44 wnd2 1247346 15:57:44 wnd3 1575014 15:57:44 wnd2 1247346 15:57:44 wnd3 1575014 15:57:44 timer end 15:57:44 ##################
Delphi-Quellcode:
var
wnd: HWND; begin wnd := FindWindow('#32770', Fenstertitel); wnd := FindWindowEx(wnd, 0, 'Button', 'Button1'); if wnd <> 0 then begin end; end; |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Ich habs jetzt mit dem Prüfen des Wertes rausbekommen :wall:. Den Code hatte ich ja schon geschrieben ...
Delphi-Quellcode:
procedure TForm1.EncodefixtimerPredTimer(Sender: TObject);
{Variablen laden} var Key: Char; wnd2: hWnd; pfad:string; begin {Timer ausschalten} EncodefixtimerPred.Enabled:=false; {Timerstart in eine Memo schreiben} memo1.lines.add(TimeToStr(time)+' '+'##################'); memo1.lines.add(TimeToStr(time)+' '+'timer start'); {Fenster suchen} wnd2 := FindWindow('#32770', PChar('Fenstertitel'); {wnd2-Wert in eine Memo schreiben} memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); {Prüfen ob Fenster existiert, wenn ja nach Button suchen} if wnd2 <> 0 then wnd2 := FindWindowEx(wnd2, 0, 'Button', 'Encode') else exit; {wnd2-Wert in eine Memo schreiben} memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); {Prüfen ob Button existiert, wenn ja Button klicken} if wnd2 <> 0 then begin SendMessage(wnd2,BM_CLICK,0,0); {wnd2-Wert in eine Memo schreiben} memo1.lines.add(TimeToStr(time)+' '+inttostr(wnd2)); end else exit; {Befehlsende des Timers in eine Memo schreiben} memo1.lines.add(TimeToStr(time)+' timer end'); memo1.lines.add(TimeToStr(time)+' ##################'); end;
Code:
Leider friert mir mein Tool immer noch ein.
16:23:50 ##################
16:23:50 timer start 16:23:50 329990 16:23:50 2230302 16:25:09 2230302 16:25:09 2230302 16:25:09 timer end 16:25:09 ################## 16:25:13 ################## 16:25:13 timer start 16:25:13 0 Hier nochmal der Befehl von meinem Tool aus:
Delphi-Quellcode:
if Startfix.text='' then EncodefixtimerPred.enabled:=false else EncodefixtimerPred.enabled:=true;
RunAndWaitShell(pchar(EXE.text), ' -Parameter1 -Parameter2 -Parameter3',value) |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Moin Amnon,
was mir auffällt: Du schreibst nur zweimal den Wert des Buttonhandles ins Memo, es steht aber dreimal drin :gruebel: Offensichtlich bewirkt das Anklicken des Buttons einen etwas zeitintensiveren Vorgang, denn der Abstand zwischen dem Eintrag vor und nach Sendmessage beträgt 1:19. Hast Du berücksichtigt, dass SendMessage erst nach Verarbeitung der Message wieder zurückkehrt? |
Re: RunAndWaitShell - FindWindowEx Konflikt ?!?
Hmm. Hab ich nicht bedacht. Wie könnte man das lösen. Sobald man auf den Button klickt wird ein anderes Fenster aktiv und ein MPEG2Film wird encodiert. Es handelt sich um einen MPEGEncoder der dadurch gestartet wird. Ich denke die einzige Lösung währe mit ShellExecute eine weitere EXE zu starten und die Parameter für den Fenstertitel der EXE mitgeben. Diese würde dann den Parameter als Fenstertitel hernehmen. Da ja nach ShellExecute der nächste Befehl RunShellandWait ausgeführt wird würde ja der Button von dem zweiten EXE-Programm geklickt, wenn der Timer abläuft.
... oder gibt es einen anderen Weg, das das Programm nicht einfriert. Mir würde sonst nichts besseres einfallen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:45 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