Einzelnen Beitrag anzeigen

doctor-x

Registriert seit: 29. Apr 2007
41 Beiträge
 
#5

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

  Alt 11. Mai 2011, 02:30
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
Wolf
  Mit Zitat antworten Zitat