unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 =
class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure GetConsoleOutput(
const Command:
String);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function IsWinNT: boolean;
var
Form1: TForm1;
implementation
{$R *.dfm}
function IsWinNT: boolean;
var
osv : OSVERSIONINFO;
begin
result := false;
try
osv.dwOSVersionInfoSize := sizeof(osv);
GetVersionEx(osv);
result := (osv.dwPlatformId = VER_PLATFORM_WIN32_NT);
except
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetConsoleOutput('
cmd /c dir c:\winnt /s');
end;
procedure TForm1.GetConsoleOutput(
const Command:
String);
var
si: TStartupInfo;
pi: TProcessInformation;
sa: TSecurityAttributes;
sd: TSECURITYDESCRIPTOR;
newstdin,newstdout,read_stdout,write_stdin:Thandle;
Succeed: Boolean;
Buffer:
array [0..1024]
of Char;
NumberOfBytesRead: DWORD;
BytesAvailable: DWORD;
//Stream: TMemoryStream;
app_spawn:
string;
exitcode : cardinal;
begin
//Initialisierung ProcessInfo
FillChar(pi, SizeOf(TProcessInformation), 0);
//Initialisierung SecurityAttr
FillChar(sa, SizeOf(TSecurityAttributes), 0);
if IsWinNT
then begin
InitializeSecurityDescriptor(@sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@sd, true,
nil, false);
sa.lpSecurityDescriptor := @sd;
end else begin
sa.lpSecurityDescriptor :=
nil;
end;
sa.nLength := SizeOf(sa);
sa.bInheritHandle := true;
if (
not CreatePipe(newstdin,write_stdin,@sa,0))
then begin
CloseHandle(newstdin);
CloseHandle(write_stdin);
exit;
//create stdin pipe
end;
if (
not CreatePipe(read_stdout,newstdout,@sa,0))
then begin //create stdout pipe
CloseHandle(read_stdout);
CloseHandle(newstdout);
exit;
end;
GetStartupInfo(si);
//set startupinfo for the spawned process
{
The dwFlags member tells CreateProcess how to make the process.
STARTF_USESTDHANDLES validates the hStd* members. STARTF_USESHOWWINDOW
validates the wShowWindow member.
}
si.dwFlags := STARTF_USESTDHANDLES
OR STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;
si.hStdOutput := newstdout;
si.hStdError := newstdout;
//set the new handles for the child process
si.hStdInput := newstdin;
app_spawn := '
c:\\window3\\system32\\cmd.exe';
//spawn the child process
// if (not CreateProcess(pchar(app_spawn),nil,nil,nil,TRUE,CREATE_NEW_CONSOLE,nil,nil,si,pi)) then begin
if (
not CreateProcess(
nil, PChar(command),
nil,
nil, true,CREATE_DEFAULT_ERROR_MODE
or CREATE_NEW_CONSOLE
or NORMAL_PRIORITY_CLASS,
nil,
nil,si,pi))
then begin
CloseHandle(newstdin);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
end else begin
//fillchar(buffer,sizeof(buffer),0);
// main loop
exitcode := 0;
while true
do begin
GetExitCodeProcess(pi.hProcess,exitcode);
//while the process is running
if (exitcode <> STILL_ACTIVE)
then break;
BytesAvailable := 0;
PeekNamedPipe(read_stdout,pchar(buffer[0]),1023,@NumberOfBytesRead,@BytesAvailable,
nil);
//check to see if there is any data to read from stdout
if (NumberOfBytesRead <> 0)
then begin
if (BytesAvailable > 1023)
then begin
while (NumberOfBytesRead >= 1023)
do begin
fillchar(buffer,sizeof(buffer),0);
ReadFile(read_stdout,buffer,1023,NumberOfBytesRead,
nil);
//read the stdout pipe
memo1.Lines.Add(buffer);
end;
end else begin
fillchar(buffer,sizeof(buffer),0);
ReadFile(read_stdout,buffer,1023,NumberOfBytesRead,
nil);
//read the stdout pipe
memo1.Lines.Add(buffer);
end;
end;
end;
// main loop
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdin);
//clean stuff up
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
end;
// process created
end;
end.