Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Externes programm starten und warten bis dieses "bereit" ist (https://www.delphipraxis.net/160386-externes-programm-starten-und-warten-bis-dieses-bereit-ist.html)

erik-17 10. Mai 2011 20:06

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

wicht 10. Mai 2011 20:12

AW: Externes programm starten und warten bis dieses "bereit" ist
 
Eventuell hiermit:

http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

HTH

OldGrumpy 10. Mai 2011 20:13

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.

WladiD 10. Mai 2011 20:31

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:
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;
In Message.LParam ist stets das Window-Handle enthalten.

Achso, die obige Prozedur muss nur aktiviert werden, bevor du das externe Programm startest.

doctor-x 11. Mai 2011 01:30

AW: Externes programm starten und warten bis dieses "bereit" ist
 
Hi,
ich hab das mal irgendwo hier gefunden udn benutze es auch :)

Code:
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;
und

Code:
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;
zum teil ging es mit CreateProcessWaitReady alleine nicht, da hab ich dann folgendes gemacht:

Code:
if not AppActivate(CMainWindowName) then begin
  CreateProcessWaitReady(ApplicationExePath, '');
  Count := 0;
  repeat
    Sleep(10);
    Inc(Count);
  until AppActivate(CMainWindowName) or (Count >= CMaxCounter);
end;
Hoffe es hilt weiter :)

MfG

himitsu 11. Mai 2011 05:48

AW: Externes programm starten und warten bis dieses "bereit" ist
 
Es gibt auch schon einige Threads dazu ... hier einige Suchworte
Hier im Forum suchenShellExecuteEx / MSDN-Library durchsuchenShellExecuteEx
Hier im Forum suchenShellExecAndWait
Hier im Forum suchenShellExecuteAndWait
Hier im Forum suchenShellExecute_AndWait

Eigentlich stand auch mal was in der CodeLib aber irgendwie kann ich's nicht mehr finden.

OldGrumpy 11. Mai 2011 10:21

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 :)

himitsu 11. Mai 2011 10:32

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:

OldGrumpy 11. Mai 2011 11:06

AW: Externes programm starten und warten bis dieses "bereit" ist
 
Zitat:

Zitat von himitsu (Beitrag 1100141)
Stümmt ... Ich trinke garkeinen Kaffee :lol:

Nja, ansonsten kann man bei ShellExecuteEx über die HINSTANCE auf die Beendigung der Anwendung warten.

Ja, aber es ging ja gar nicht um die Beendigung sondern nur darum zu warten bis die Anwendung komplett gestartet ist und "aufnahmebereit" wird :)

himitsu 11. Mai 2011 11:26

AW: Externes programm starten und warten bis dieses "bereit" ist
 
Zitat:

Zitat von OldGrumpy (Beitrag 1100146)
Ja, aber es ging ja gar nicht um die Beendigung sondern nur darum zu warten bis die Anwendung komplett gestartet ist und "aufnahmebereit" wird :)

Das könnte man ja auch prüfen > über die HINSTANCE hat man den Prozess, darüber kann man die Hauptfenster suchen
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 05:18 Uhr.
Seite 1 von 2  1 2      

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