Registriert seit: 12. Mär 2003
Ort: Kempten
188 Beiträge
Delphi 6 Enterprise
|
Prozess starten + Rückgabewert für Delphi 2009
26. Jan 2009, 15: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
|
|
Zitat
|