以前做的一个测试。<br>uMain.pas<br>========================================<br>unit uMain;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls, ExtCtrls, ShellCtrls;<br>const<br> ReadBuffer = 255;<br>type<br> TForm1 = class(TForm)<br> Memo1: TMemo;<br> Timer1: TTimer;<br> Panel1: TPanel;<br> ComboBox1: TComboBox;<br> procedure FormCreate(Sender: TObject);<br> procedure FormClose(Sender: TObject; var Action: TCloseAction);<br> procedure Timer1Timer(Sender: TObject);<br> procedure ComboBox1KeyPress(Sender: TObject; var Key: Char);<br> procedure ComboBox1Select(Sender: TObject);<br> procedure Memo1KeyPress(Sender: TObject; var Key: Char);<br> private<br> procedure WriteToPipe(Pipe: THandle; Value: string);<br> function ReadFromPipe(Pipe: THandle): string;<br> { Private declarations }<br> public<br> ReadPipeIn, WritePipeIn,ReadPipeOut, WritePipeOut: THandle;<br> ProcessInfo: TProcessInformation;<br> Buffer: PChar;<br> BytesRead: DWord;<br> bStart:boolean;<br> s:Tstringlist;<br> end;<br><br>var<br> Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>Security: TSecurityAttributes;<br>start: TStartUpInfo;<br>begin<br><br> // s.Destroy;<br> with Security do<br> begin<br> nlength := SizeOf(TSecurityAttributes);<br> binherithandle := true;<br> lpsecuritydescriptor := nil;<br> end;<br><br> {创建一个命名管道用来捕获console程序的输出}<br><br><br> if not Createpipe(ReadPipeIn, WritePipeIn, @Security, 0) then<br> begin<br> showmessage('无法创建命名管道!');<br> exit;<br> end;<br> if not Createpipe(ReadPipeOut, WritePipeOut, @Security, 0) then<br> begin<br> showmessage('无法创建命名管道!');<br> CloseHandle(ReadPipeIn);<br> CloseHandle(WritePipeIn);<br> exit;<br> end;<br><br> Buffer := AllocMem(ReadBuffer + 1);<br><br> FillChar(Start, Sizeof(Start), #0);<br> {设置console程序的启动属性}<br> with start do<br> begin<br> cb := SizeOf(start);<br> start.lpReserved := nil;<br> lpDesktop := nil;<br> lpTitle := nil;<br> dwX := 0;<br> dwY := 0;<br> dwXSize := 0;<br> dwYSize := 0;<br> dwXCountChars := 0;<br> dwYCountChars := 0;<br> dwFillAttribute := 0;<br> cbReserved2 := 0;<br> lpReserved2 := nil;<br> hStdOutput := WritePipeOut; //将输出定向到我们建立的WritePipe上<br> hStdInput := ReadPipeIn; //将输入定向到我们建立的ReadPipeIn上<br> hStdError := WritePipeOut; //将错误输出定向到我们建立的WritePipe上<br> dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;<br> wShowWindow := SW_hide; //设置窗口为hide<br> end;<br><br> if not CreateProcess(nil,<br> PChar('cmd.exe'),<br> @Security,<br> @Security,<br> true,<br> NORMAL_PRIORITY_CLASS,<br> nil,<br> nil,<br> start,<br> ProcessInfo)<br> then<br> begin<br> showmessage('无法起动cmd!');<br> exit;<br> end;<br> Memo1.Lines.Add('程序起动');<br> BytesRead := 0;<br> self.bStart :=true;<br><br>end;<br>procedure TForm1.WriteToPipe(Pipe: THandle; Value: string);<br>var<br> len: integer;<br> BytesWrite: DWord;<br> Buffer: PChar;<br>begin<br> len := Length(Value) + 2;<br> Buffer := PChar(Value + #13#10);<br> WriteFile(Pipe, Buffer[0], len, BytesWrite, nil);<br>end;<br><br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br> if self.bStart then<br> begin<br> TerminateProcess(ProcessInfo.hProcess,0);<br> FreeMem(Buffer);<br> CloseHandle(ProcessInfo.hProcess);<br> CloseHandle(ProcessInfo.hThread);<br> CloseHandle(ReadPipeOut);<br> CloseHandle(WritePipeOut);<br> CloseHandle(ReadPipeIn);<br> CloseHandle(WritePipeIn);<br> end;<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> Buf: string;<br> fileSize:dword;<br>begin<br> buf:= ReadFromPipe( ReadPipeOut);<br><br> if buf <>'' then<br> begin<br> Memo1.Lines.BeginUpdate ;<br> Memo1.Text := Memo1.Text + buf;<br> postmessage(Memo1.Handle,EM_SCROLL,SB_BOTTOM,0);<br> application.ProcessMessages;<br> memo1.SelStart := length(Memo1.Text);<br> Memo1.Lines.EndUpdate;<br> end;<br>end;<br><br>function TForm1.ReadFromPipe(Pipe: THandle): string;<br>var<br> Buffer: PChar;<br> BytesRead: DWord;<br>begin<br> Result := '';<br><br> if GetFileSize(Pipe, nil) = 0 then Exit;<br><br> Buffer := AllocMem(ReadBuffer + 1);<br><br> repeat<br> BytesRead := 0;<br> ReadFile(Pipe, Buffer[0],<br> ReadBuffer, BytesRead, nil);<br> if BytesRead > 0 then begin<br> Buffer[BytesRead] := #0;<br> OemToAnsi(Buffer, Buffer);<br> Result := Result+string(Buffer);<br> end;<br> until (GetFileSize(Pipe, nil) <= 0);<br><br> FreeMem(Buffer);<br><br>end;<br><br>procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);<br>begin<br> if Key = #13 then<br> begin<br> //向管道写入数据。<br> WriteToPipe(WritePipeIn,ComboBox1.Text);<br><br> Key :=#0;<br> if (ComboBox1.Text <> '')then<br> begin<br> ComboBox1.Items.Insert(0,ComboBox1.Text);<br> if ComboBox1.Items.Count > 20 then<br> ComboBox1.Items.Delete(ComboBox1.Items.Count -1);<br> ComboBox1.Text:='';<br> ComboBox1.ItemIndex:=-1;<br> end;<br> end;<br> ComboBox1.Tag:= ComboBox1.SelStart ;<br>end;<br><br>procedure TForm1.ComboBox1Select(Sender: TObject);<br>begin<br> if length(ComboBox1.Text) <=ComboBox1.Tag then<br> ComboBox1.SelStart := ComboBox1.Tag ;<br>end;<br><br>procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);<br>begin<br> PostMessage(ComboBox1.Handle,WM_CHAR, integer(Key),0);<br> Key:=#0;<br> ComboBox1.SetFocus;<br>end;<br><br>end.<br><br><br><br>uMain.DFM<br>========================================================================<br>object Form1: TForm1<br> Left = 273<br> Top = 444<br> Width = 870<br> Height = 673<br> Caption = 'Form1'<br> Color = clBtnFace<br> Font.Charset = DEFAULT_CHARSET<br> Font.Color = clWindowText<br> Font.Height = -11<br> Font.Name = 'MS Sans Serif'<br> Font.Style = []<br> OldCreateOrder = False<br> OnClose = FormClose<br> OnCreate = FormCreate<br> PixelsPerInch = 96<br> TextHeight = 13<br> object Memo1: TMemo<br> Left = 0<br> Top = 0<br> Width = 862<br> Height = 616<br> Align = alClient<br> Color = clMenuText<br> Font.Charset = ANSI_CHARSET<br> Font.Color = clWhite<br> Font.Height = -16<br> Font.Name = 'System'<br> Font.Style = [fsBold]<br> Lines.Strings = (<br> 'Memo1')<br> ParentFont = False<br> ScrollBars = ssVertical<br> TabOrder = 0<br> OnKeyPress = Memo1KeyPress<br> end<br> object Panel1: TPanel<br> Left = 0<br> Top = 616<br> Width = 862<br> Height = 23<br> Align = alBottom<br> Caption = 'Panel1'<br> TabOrder = 1<br> DesignSize = (<br> 862<br> 23)<br> object ComboBox1: TComboBox<br> Left = 0<br> Top = 0<br> Width = 865<br> Height = 21<br> AutoComplete = False<br> BevelInner = bvSpace<br> BevelKind = bkSoft<br> BevelOuter = bvNone<br> Anchors = [akLeft, akRight, akBottom]<br> ItemHeight = 13<br> TabOrder = 0<br> OnKeyPress = ComboBox1KeyPress<br> OnSelect = ComboBox1Select<br> end<br> end<br> object Timer1: TTimer<br> Interval = 10<br> OnTimer = Timer1Timer<br> Left = 8<br> Top = 48<br> end<br>end