Einzelnen Beitrag anzeigen

Zerolith

Registriert seit: 12. Mär 2003
Ort: Kempten
188 Beiträge
 
Delphi 6 Enterprise
 
#1

Prozess starten + Rückgabewert für Delphi 2009

  Alt 26. Jan 2009, 14:54
Habe heute nach genau so einer Funktion hier gesucht. Musste aber für Delphi 2009 ein paar Anpassungen machen.
(Leider find ich den Link grad nicht mehr)

Konnte den Code hier nur mit 2009 und XP testen. Theoretisch müsste es schon mit Delphi 6 funktionieren.

Hoffe es hilft jemandem.

Delphi-Quellcode:
function RunWaitAndCaptureOutput(CommandLine: ansistring; var Output: ansistring): DWord;
const
  BufSize = 1024;
var
  buf: array[0..BufSize - 1] of ansichar;
  si: STARTUPINFOA;
  sa: SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
  pi: PROCESS_INFORMATION;
  newstdout, read_stdout: THandle;
  bytes_read: cardinal;
  bytes_available: cardinal;

  procedure ZeroBuffer;
  begin
    FillChar(Buf, SizeOf(Buf), 0);
  end;

  procedure RaiseError(str: string);
  var
    n: DWord;
  begin
    n := GetLastError;
    raise EReadError.CreateFmt('%s: %d/0x%x -%s', [Str, n, n, SysErrorMessage(n)]);
  end;

  procedure GetData;
  begin
    PeekNamedPipe(read_stdout, @buf, BufSize - 1, @bytes_read, @bytes_available, nil);
    if (bytes_read <> 0) then
    begin
      ZeroBuffer;
      if (bytes_available > BufSize - 1)
        then
        while (bytes_read >= BufSize - 1) do
        begin
          ReadFile(read_stdout, buf, BufSize - 1, bytes_read, nil);
          Output := Output + Buf;
          ZeroBuffer;
        end
      else
      begin
        ReadFile(read_stdout, buf, BufSize - 1, bytes_read, nil);
        Output := Output + Buf;
      end;
    end;
  end;

begin
  Output := '';
  Result := 255;

  if IsWindowsNT then
  begin
    InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(@sd, true, nil, False);
    sa.lpSecurityDescriptor := @sd;
  end else
    sa.lpSecurityDescriptor := nil;

  sa.nLength := sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle := true; //allow inheritable handles

  if not (CreatePipe(read_stdout, newstdout, @sa, 0)) then
    RaiseError('CreatePipe');

  GetStartupInfoA(si);

  si.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
  si.wShowWindow := SW_HIDE;
  si.hStdOutput := newstdout;
  si.hStdError := newstdout;

  if not (CreateProcessA(nil, PAnsiChar(CommandLine), nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi)) then
  begin
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    RaiseError('CreateProcess');
  end;

  ZeroBuffer;
  while True do
  begin
    GetExitCodeProcess(pi.hProcess, Result);
    if (Result <> STILL_ACTIVE) then break;
    GetData;
  end;

  GetData;

  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
end;
Daniel
  Mit Zitat antworten Zitat