Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

externe processen in Delphi NA elkaar laten plaatsvinden

musicom76
3 antwoorden
  • Hallo. Ik zit met het volgende: Ik wil in Delphi een extern proces opstarten, een
    executable met parameters. Maar de applicatie wil ik daarop laten wachten. Hoe krijg ik dit
    voor elkaar ? Als ik met de volgende code 4 processen oproep, wordt deze executable 4 x tegelijk
    opgestart en die zijn ongeveer tegelijk klaar. Maar ik wil graag dat ze NA elkaar plaatsvinden.

    for i := 0 to 3 do
    begin
    ShellExecute(handle, 'open', "proces.exe", nil, nil, SW_SHOWMINIMIZE);

    Ik heb geprobeerd om dit erbij te plakken:
    waitresult := WaitForSingleObject(handle, INFINITE);
    end;

    Maar dit werkt niet, het waitresult geeft WAIT_FAILED. Misschien is dit ook wel helemaal niet
    de manier om dit te doen… Weet iemand mij te helpen ?
  • Helaas kun je de handle die ShellExecute returned niet gebruiken voor WaitForSingleObject. Met ShellExecuteEx gaat het wel:
    [code:1:94689f6ecc]
    function ShellExecuteWait(const CommandLine, Parameters: string): dword;
    var
    ShellExecuteInfo: TShellExecuteInfo;
    ExitCode: dword;
    begin
    FillChar(ShellExecuteInfo, SizeOf(ShellExecuteInfo), 0);
    with ShellExecuteInfo do
    begin
    cbSize := SizeOf(ShellExecuteInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := Application.Handle;
    lpFile := pchar(CommandLine);
    lpParameters := pchar(Parameters);
    nShow := SW_SHOWNORMAL;
    end;
    if not ShellExecuteEx(@ShellExecuteInfo) then
    raise Exception.CreateFmt('Unable to execute %s (%d)',
    [CommandLine, GetLastError]);
    if WaitForSingleObject(ShellExecuteInfo.hProcess, INFINITE) = WAIT_FAILED then
    raise Exception.CreateFmt('Error waiting for process %s (%d)',
    [CommandLine, GetLastError]);
    if not GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode) then
    raise Exception.CreateFmt('Unable to get exit code from %s (%d)',
    [CommandLine, GetLastError]);
    if not CloseHandle(ShellExecuteInfo.hProcess) then
    raise Exception.CreateFmt('Unable close handle for %s (%d)',
    [CommandLine, GetLastError]);
    Result := ExitCode;
    end;
    [/code:1:94689f6ecc]
  • [quote:6c70c6c166="musicom76"]Ik wil in Delphi een extern proces opstarten, een executable met parameters. Maar de applicatie wil ik daarop laten wachten. Hoe krijg ik dit voor elkaar ?[/quote:6c70c6c166]
    [code:1:6c70c6c166]
    {– WinExecAndWait32V2 ————————————————}
    {: Executes a program and waits for it to terminate
    @Param FileName contains executable + any parameters
    @Param Visibility is one of the ShowWindow options, e.g. SW_SHOWNORMAL
    @Returns -1 in case of error, otherwise the programs exit code
    @Desc In case of error SysErrorMessage( GetlastError ) will return an
    error message. The routine will process paint messages and messages
    send from other threads while it waits.
    }{ Created 27.10.2000 by P. Below
    ———————————————————————–}
    Function WinExecAndWait32V2( FileName: String; Visibility: integer ):
    DWORD;
    Procedure WaitFor( processHandle: THandle );
    Var
    msg: TMsg;
    ret: DWORD;
    Begin
    Repeat
    ret := MsgWaitForMultipleObjects(
    1, { 1 handle to wait on }
    processHandle, { the handle }
    False, { wake on any event }
    INFINITE, { wait without timeout }
    QS_PAINT or { wake on paint messages }
    QS_SENDMESSAGE { or messages from other threads }
    );
    If ret = WAIT_FAILED Then Exit; { can do little here }
    If ret = (WAIT_OBJECT_0 + 1) Then Begin
    { Woke on a message, process paint messages only. Calling
    PeekMessage gets messages send from other threads processed.
    }
    While PeekMessage( msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE ) Do
    DispatchMessage( msg );
    End;
    Until ret = WAIT_OBJECT_0;
    End; { Waitfor }
    Var { V1 by Pat Ritchey, V2 by P.Below }
    zAppName:array[0..512] of char;
    StartupInfo:TStartupInfo;
    ProcessInfo:TProcessInformation;
    Begin { WinExecAndWait32V2 }
    StrPCopy(zAppName,FileName);
    FillChar(StartupInfo,Sizeof(StartupInfo),#0);
    StartupInfo.cb := Sizeof(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := Visibility;
    If not CreateProcess(nil,
    zAppName, { pointer to command line string }
    nil, { pointer to process security attributes }
    nil, { pointer to thread security attributes }
    false, { handle inheritance flag }
    CREATE_NEW_CONSOLE or { creation flags }
    NORMAL_PRIORITY_CLASS,
    nil, { pointer to new environment block }
    nil, { pointer to current directory name }
    StartupInfo, { pointer to STARTUPINFO }
    ProcessInfo) { pointer to PROCESS_INF }
    Then
    Result := DWORD(-1) { failed, GetLastError has error code }
    Else Begin
    Waitfor(ProcessInfo.hProcess);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle( ProcessInfo.hProcess );
    CloseHandle( ProcessInfo.hThread );
    End; { Else }
    End; { WinExecAndWait32V2 }[/code:1:6c70c6c166]

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.