Delphi中的管道用于命令提示符
发布时间:2020-12-15 09:28:33 所属栏目:大数据 来源:网络整理
导读:如何让Delphi将字符串传递给CMD进程的输入管道.我能够得到一个错误管道和输出管道正常运行,不幸的是不是输入管道.我正在使用的代码取自管道的在线教程.原始代码中有几个错误在编译时导致问题.它们已被修复,但在尝试传递输入时仍然存在问题. 这是Form.Create
如何让Delphi将字符串传递给CMD进程的输入管道.我能够得到一个错误管道和输出管道正常运行,不幸的是不是输入管道.我正在使用的代码取自管道的在线教程.原始代码中有几个错误在编译时导致问题.它们已被修复,但在尝试传递输入时仍然存在问题.
这是Form.Create事件中的代码.我还包括WritePipe和ReadPipe方法. WritePipe不起作用,ReadPipe确实有效. Pipe方法中的WriteFile和ReadFile都返回一条成功的消息,但只有ReadPipe才能正常工作. var DosApp: String; DosSize: Integer; Security : TSecurityAttributes; start : TStartUpInfo; byteswritten: DWord; WriteString : ansistring; begin CommandText.Clear; // get COMSPEC variable,this is the path of the command-interpreter SetLength(Dosapp,255); DosSize := GetEnvironmentVariable('COMSPEC',@DosApp[1],255); SetLength(Dosapp,DosSize); // create pipes With Security do begin nlength := SizeOf(TSecurityAttributes) ; binherithandle := true; lpsecuritydescriptor := nil; end; CreatePipe(InputPipeRead,InputPipeWrite,@Security,0); CreatePipe(OutputPipeRead,OutputPipeWrite,0); CreatePipe(ErrorPipeRead,ErrorPipeWrite,0); // start command-interpreter FillChar(Start,Sizeof(Start),#0) ; //start.hStdInput := InputPipeRead; start.hStdOutput := OutputPipeWrite; start.hStdError := ErrorPipeWrite; start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; start.wShowWindow := SW_Show;//SW_HIDE; start.cb := SizeOf(start) ; if CreateProcess('',PChar(DosApp),true,CREATE_NEW_CONSOLE or SYNCHRONIZE,// CREATE_NO_WINDOW,nil,start,ProcessInfo) then begin MyThread := MainUnit.monitor.Create; // start monitor thread MyThread.Priority := tpHigher; end; Button1.Enabled := true; cmdcount := 1; end; 写管道: procedure WritePipeOut(OutputPipe: THandle; InString: PWideChar); // writes Instring to the pipe handle described by OutputPipe var count : integer; byteswritten: DWord; outputstring : PAnsiChar; TextBuffer: array[1..32767] of AnsiChar;// char; TextString: String; begin // most console programs require CR/LF after their input. InString := PWideChar(InString + #13#10); WriteFile(InputPipeWrite,InString[1],Length(InString),byteswritten,nil); end; 读管: function ReadPipeInput(InputPipe: THandle; var BytesRem: Integer): String; { reads console output from InputPipe. Returns the input in function result. Returns bytes of remaining information to BytesRem } var TextBuffer: array[1..32767] of AnsiChar;// char; TextString: String; BytesRead: Cardinal; PipeSize: Integer; begin Result := ''; PipeSize := length(TextBuffer); // check if there is something to read in pipe PeekNamedPipe(InputPipe,PipeSize,@BytesRead,@PipeSize,@BytesRem); if bytesread > 0 then begin ReadFile(InputPipe,TextBuffer,pipesize,bytesread,nil); // a requirement for Windows OS system components OemToChar(@TextBuffer,@TextBuffer); TextString := String(TextBuffer); SetLength(TextString,BytesRead); Result := TextString; end; end; 进一步说明;这是为了与Java调试器一起使用,它需要分阶段输入,所以我不相信除了直接操作输入到JDB之外还有任何替代方法. 任何帮助深表感谢! 解决方法
1)您应该将InputPipeRead作为hStdInput传递给CreateProcess:取消注释你的行start.hStdInput:= InputPipeRead;
2)WritePipeOut函数有两个错误:它将Unicode(UTF-16LE)字符串写入管道,并跳过第一个字符(因为它写入一个以InString [1]开头的内存区域).而不是WriteFile(InputPipeWrite,InString [1],…你应该写如下: var AnsiBuf: AnsiString; ... AnsiBuf := String(InString) + #13#10; Write(InputPipeWrite,AnsiBuf[1],Length(AnsiBuf),nil); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |