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: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173:
| Procedure TheCallBack(s:String); var ansi:String; begin Setlength(ansi,length(s)); OemToAnsi(Pchar(s),Pchar(ansi)); Form1.Memo1.Text:=Form1.Memo1.Text+ansi; end;
procedure TForm1.Button1Click(Sender: TObject); begin
cs:=TConsoleThread.Create('cmd /C CD \|dir'#13#10, '','',TheCallBack);
cs.Resume; end;
unit ConsoleThread; interface
uses Windows,Classes,Forms,Dialogs;
Type TCallBackProcedure = Procedure (Result:String); TConsoleThread = class(TThread) private FEnvironment,FOutPut,FErrors,FInput,FCommand:String; FCallBackProcedure:TCallBackProcedure; FCurrentOutPut:String; FOK:Boolean; protected procedure Execute; override; Procedure SendCallBack; public constructor Create(const Command,Input, Environment:String;CallBackProcedure:TCallBackProcedure); end;
implementation
Procedure TConsoleThread.SendCallBack; begin FCallBackProcedure(FCurrentOutPut); end;
constructor TConsoleThread.Create(const Command,Input, Environment:String;CallBackProcedure:TCallBackProcedure); begin FCallBackProcedure:=CallBackProcedure; FreeOnTerminate:=true; FInput:=Input; FEnvironment:=Environment; FCommand:=Command; inherited Create(true); end;
Procedure TConsoleThread.Execute; var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; SecurityAttr: TSecurityAttributes; PipeOutputRead: THandle; PipeOutputWrite: THandle; PipeInputWrite: THandle; PipeInputRead: THandle; PipeErrorsRead: THandle; PipeErrorsWrite: THandle; Succeed: Boolean; Buffer: array [0..255] of Char; NumberOfBytesRead: DWORD; Stream: TMemoryStream; p:PChar ; begin
FOutput := ''; FErrors := ''; FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0); SecurityAttr.nLength := SizeOf(SecurityAttr); SecurityAttr.bInheritHandle := true; SecurityAttr.lpSecurityDescriptor := nil;
CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0); CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0); CreatePipe(PipeInputRead, PipeInputWrite, @SecurityAttr, 0);
WriteFile(PipeInputWrite, FInput[1], Length(FInput), NumberOfBytesRead, nil);
FillChar(StartupInfo, SizeOf(TStartupInfo), 0); StartupInfo.cb:=SizeOf(StartupInfo); StartupInfo.hStdInput := PipeInputRead; StartupInfo.hStdOutput := PipeOutputWrite; StartupInfo.hStdError := PipeErrorsWrite; StartupInfo.wShowWindow := sw_Hide; StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; if Length(FEnvironment)=0 then p:=nil else p:=PChar(FEnvironment);
if CreateProcess(nil, PChar(Fcommand), nil, nil, true, CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, p, nil, StartupInfo, ProcessInfo) then begin FOK:=true; CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsWrite); CloseHandle(PipeInputWrite); CloseHandle(PipeInputRead);
Stream := TMemoryStream.Create; try while true do begin succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; Stream.Write(Buffer, NumberOfBytesRead);
FCurrentOutPut:=Copy(buffer,1,NumberOfBytesRead); if Assigned(FCallBackProcedure) then Synchronize(SendCallBack); Application.ProcessMessages; end; Stream.Position := 0; SetLength(FOutput, Stream.Size); if Stream.Size > 0 then Stream.Read(FOutput[1], Stream.Size) finally Stream.Free; end; CloseHandle(PipeOutputRead); Stream := TMemoryStream.Create; try while true do begin succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; Stream.Write(Buffer, NumberOfBytesRead); FCurrentOutPut:=Copy(buffer,1,NumberOfBytesRead); if Assigned(FCallBackProcedure) then Synchronize(SendCallBack); Application.ProcessMessages; end; Stream.Position := 0; SetLength(FErrors, Stream.Size); if Stream.Size > 0 then Stream.Read(FErrors[1], Stream.Size) finally Stream.Free; end; CloseHandle(PipeErrorsRead); WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hProcess); end else begin FOK:=false; CloseHandle(PipeOutputRead); CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsRead); CloseHandle(PipeErrorsWrite); end; end; end. |