-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathconsole.pas
115 lines (99 loc) · 3.23 KB
/
console.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// ******************************************************************************
// Code to retrieve the output of a console window.
// code taken from:
// http://www.delphipraxis.net/164364-doskonsole-nutzen-und-rueckgabewerte-einlesen.html
// ******************************************************************************
unit console;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
var
SATPID: DWord;
function GetConsoleOutput(Command: string; Output, Errors: TStringList)
: Boolean;
implementation
function GetConsoleOutput(Command: string; Output, Errors: TStringList)
: Boolean;
var
Buffer: array [0 .. 255] of Char;
CreationFlags: DWord;
NumberOfBytesRead: DWord;
PipeErrorsRead: THandle;
PipeErrorsWrite: THandle;
PipeOutputRead: THandle;
PipeOutputWrite: THandle;
ProcessInfo: TProcessInformation;
SecurityAttr: TSecurityAttributes;
StartupInfo: TStartupInfo;
Stream: TMemoryStream;
begin
// Initialisierung ProcessInfo
FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
// Initialisierung SecurityAttr
FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
SecurityAttr.nLength := SizeOf(TSecurityAttributes);
SecurityAttr.bInheritHandle := True;
SecurityAttr.lpSecurityDescriptor := nil;
// Pipes erzeugen
CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);
// Initialisierung StartupInfo
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.hStdInput := 0;
StartupInfo.hStdOutput := PipeOutputWrite;
StartupInfo.hStdError := PipeErrorsWrite;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
CreationFlags := CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS;
// Folgende Zeile ist nur für Delphi ab 2009 erforderlich:
UniqueString(Command);
if CreateProcess(nil, PChar(Command), nil, nil, True, CreationFlags, nil, nil,
StartupInfo, ProcessInfo) then
begin
Result := True;
SATPID:= ProcessInfo.dwProcessId;
// Write-Pipes schließen
CloseHandle(PipeOutputWrite);
CloseHandle(PipeErrorsWrite);
// Ausgabe Read-Pipe auslesen
Stream := TMemoryStream.Create;
try
while ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil) do
begin
Stream.Write(Buffer, NumberOfBytesRead);
end;
Stream.Position := 0;
Output.LoadFromStream(Stream);
finally
Stream.Free;
end;
CloseHandle(PipeOutputRead);
// Fehler Read-Pipe auslesen
Stream := TMemoryStream.Create;
try
while ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil) do
begin
Stream.Write(Buffer, NumberOfBytesRead);
end;
Stream.Position := 0;
Errors.LoadFromStream(Stream);
finally
Stream.Free;
end;
CloseHandle(PipeErrorsRead);
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
CloseHandle(ProcessInfo.hProcess);
end
else
begin
Result := False;
CloseHandle(PipeOutputRead);
CloseHandle(PipeOutputWrite);
CloseHandle(PipeErrorsRead);
CloseHandle(PipeErrorsWrite);
end;
end;
end.