![]() |
Externes programm starten und warten bis dieses "bereit" ist
Hallo,
ich hab ein Problem: Mein Programm ruft ein anderes Programm auf, und soll nun solange nichts tun (warten), bis dieses andere Programm sozusagen bereit ist. In meinem Fall ist es Firefox, der starten soll. (Weil der nicht immer gleich lange braucht, ist sleep unangebracht :( ). Habt ihr dafür vielleicht irgendwelche Ideen. Meine einzige ist: immer wieder zu prüfen, ob der andere Prozess schon eine bestimmte Ram-Größe eingenommen hat und darauf dann zu regieren. Aber wie stellt man so etwas an ?? Danke schon im voraus :-D |
AW: Externes programm starten und warten bis dieses "bereit" ist
|
AW: Externes programm starten und warten bis dieses "bereit" ist
Wenn Du den fremden Prozess via CreateProcess starten kannst, dann kannst Du einfach die WinAPI-Funktion WaitForInputIdle verwenden. Abhängig vom fremden Programm kann das aber auch in die Hose gehen, da geht Probieren vor Studieren.
|
AW: Externes programm starten und warten bis dieses "bereit" ist
Schaue dir mal die Komponente TJvShellHook aus der JVCL an.
Das Event OnShellMessage kannst du dann verarbeiten:
Delphi-Quellcode:
In Message.LParam ist stets das Window-Handle enthalten.
procedure TForm1.ShellHookDispatcher(Sender:TObject; var Message:TMessage);
begin case Message.WParam of HSHELL_WINDOWCREATED: // Fenster erstellt HSHELL_WINDOWACTIVATED, HSHELL_RUDEAPPACTIVATED: // Der nächste Sprung hierher nach // HSHELL_WINDOWCREATED bedeutet, // dass das Fenster bereit ist... end; end; Achso, die obige Prozedur muss nur aktiviert werden, bevor du das externe Programm startest. |
AW: Externes programm starten und warten bis dieses "bereit" ist
Hi,
ich hab das mal irgendwo hier gefunden udn benutze es auch :)
Code:
und
Function CreateProcessWaitReady(ProgramFile: String; Commandline: String = ''; CurrDir: String = '.'): Boolean;
Var StartInfo: TStartupInfo; ProcInfo: TProcessInformation; WFSO: DWORD; SMT_Count: Integer; SMT_Done: Boolean; Type TEWPInfo = Packed Record PI: PProcessInformation; SMTD: PBoolean; End; PEWPInfo = ^TEWPInfo; Var EWPI: TEWPInfo; Function ETWProc(wnd: HWND; Param: PEWPInfo): Boolean; Stdcall; Var Res: DWORD; Begin If SendMessageTimeoutA( wnd, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 50, Res) <> 0 Then Begin Param.SMTD^ := True; Sleep(10); End; Result := Not Param.SMTD^; End; Begin FillChar(StartInfo, SizeOf(TStartupInfo), #0); FillChar(ProcInfo, SizeOf(TProcessInformation), #0); StartInfo.cb := SizeOf(TStartupInfo); StartInfo.dwFlags := STARTF_USESHOWWINDOW Or STARTF_USEPOSITION Or STARTF_USESIZE; StartInfo.wShowWindow := SW_SHOW; Commandline := Format('"%s" %s', [ProgramFile, Trim(Commandline)]); Result := CreateProcess( Nil, pChar(Commandline), Nil, Nil, true, NORMAL_PRIORITY_CLASS, Nil, pChar(CurrDir), StartInfo, ProcInfo ); If Result Then Begin SMT_Count := 0; EWPI.PI := @ProcInfo; EWPI.SMTD := @SMT_Done; Repeat //At first check if the process is still running (and lower CPU load) ... WFSO := WaitForSingleObject(ProcInfo.hProcess, 100); //Now check for at least one window that SMT_Done := False; EnumThreadWindows(ProcInfo.dwThreadId, @ETWProc, Integer(@EWPI)); If SMT_Done Then Inc(SMT_Count) Else SMT_Count := 0; Until (WAIT_OBJECT_0 = WFSO) Or (SMT_Count >= 10); Result := SMT_Count >= 10; End; If ProcInfo.hProcess <> 0 Then CloseHandle(ProcInfo.hProcess); End;
Code:
zum teil ging es mit CreateProcessWaitReady alleine nicht, da hab ich dann folgendes gemacht:
function AppActivate(const WindowName: PChar) : Boolean;
var WindowHandle: THandle; function EnumWindowsProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall; const MAX_WINDOW_NAME_LEN = 80; var WindowName: array[0..MAX_WINDOW_NAME_LEN] of char; begin {Can't test GetWindowText's return value since some windows don't have a title} GetWindowText(WHandle, WindowName, MAX_WINDOW_NAME_LEN); Result := (StrLIComp(WindowName, PChar(lParam), StrLen(PChar(lParam))) <> 0); if (not Result) then WindowHandle := WHandle; end; begin try Result := True; WindowHandle := FindWindow(nil, WindowName); if (WindowHandle = 0) then EnumWindows(@EnumWindowsProc, Integer(PChar(WindowName))); if (WindowHandle <> 0) then begin SendMessage(WindowHandle, WM_SYSCOMMAND, SC_HOTKEY, WindowHandle); SendMessage(WindowHandle, WM_SYSCOMMAND, SC_RESTORE, WindowHandle); Sleep(100); end else Result := False; except on Exception do Result := False; end; end;
Code:
Hoffe es hilt weiter :)
if not AppActivate(CMainWindowName) then begin
CreateProcessWaitReady(ApplicationExePath, ''); Count := 0; repeat Sleep(10); Inc(Count); until AppActivate(CMainWindowName) or (Count >= CMaxCounter); end; MfG |
AW: Externes programm starten und warten bis dieses "bereit" ist
Es gibt auch schon einige Threads dazu ... hier einige Suchworte
![]() ![]() ![]() ![]() ![]() Eigentlich stand auch mal was in der CodeLib aber irgendwie kann ich's nicht mehr finden. |
AW: Externes programm starten und warten bis dieses "bereit" ist
Uh, Himitsu, ShellExecuteEx und Co sind eine andere Baustelle... :) Ich vermute mal Kaffeemangel? ;)
Für ShellExecuteEx gibts doch tatsächlich ein relativ gut verstecktes Flag das den gleichen Zweck erfüllt wie WaitForInputIdle :) |
AW: Externes programm starten und warten bis dieses "bereit" ist
Stümmt ... Ich trinke garkeinen Kaffee :lol:
Nja, ansonsten kann man bei ShellExecuteEx über die HINSTANCE auf die Beendigung der Anwendung warten. So wurde es zumintestens mal in dem CodeLib-Eintrag gemacht ....... damals im alten Forum. :gruebel: |
AW: Externes programm starten und warten bis dieses "bereit" ist
Zitat:
|
AW: Externes programm starten und warten bis dieses "bereit" ist
Zitat:
und auf gewisse Eigenschaften hin prüfen > ist ein bestimmtes Fenster vorhanden, haben darin gewisse Elemente einen bestimmten status, werden Messages verarbeitet usw. Wobei es erstmal etwas schwer wird zu definieren was "bereit" nun eigentlich ist und welche Zustände man demnach prüfen müßte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:05 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