捕获所有命令输出
Capture all commands output
我想捕获 cmd.exe 输出并在我制作的不同图形用户界面中显示它。我想制作一个具有扩展功能的命令解释器。 dir 命令运行完美,当我尝试执行另一个进程如 ipconfig 时出现问题。
我没有看到 ipconfig 输出。有解决办法吗?!
我使用来自 Lazarus (FreePascal) 的 TProcess 组件
proc := TProcess.Create(nil);
proc.Options:= [poUsePipes, poNoConsole];
proc.ShowWindow:= swoHIDE;
proc.Executable:= 'cmd';
读取输出线程:
if (Length(cmd) > 0) then
begin
cmd := cmd + #13#10;
proc.Input.Write(cmd[1], Length(cmd)); // here I write command from user
strikes := 0;
end
else
if proc.Output.NumBytesAvailable > 0 then
begin
while proc.Output.NumBytesAvailable > 0 do
begin
FillChar(buf, sizeof(buf), #0);
proc.Output.Read(buf, sizeof(buf) - 1);
data := data + buf;
end;
// data gets echoed to user
它对我来说很好(我使用 FPC 3.1.1 和 Lazarus 1.5,但我希望它没关系):
proc.Options:= [poUsePipes];
proc.ShowWindow:= swoHIDE;
proc.Executable:= 'cmd';
...
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
cmd: String;
begin
if Key = #13 then
begin
Key := #0;
if not proc.Active then
proc.Active := True;
cmd := Edit1.Text + LineEnding;
proc.Input.Write(cmd[1], Length(cmd));
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
buf: array[0..65535] of Char;
begin
if proc.Output.NumBytesAvailable > 0 then
begin
while proc.Output.NumBytesAvailable > 0 do
begin
FillChar(buf, sizeof(buf), #0);
proc.Output.Read(buf, sizeof(buf) - 1);
Memo1.Lines.Add(buf);
end;
end;
end;
我猜你只是没有正确捕获进程输出。
祝你好运。
PS:如果您需要创建一些 windows 类似控制台的应用程序,我认为最好的方法是使用 Windows console API 而不是跨平台的 Lazarus 组件。
PPS:要使用 Lazarus 模拟控制台外观和行为,请使用 CmdLine 组件。
通常明智的做法是首先检查简短示例是否不能解决问题:
例如
uses process;
var s : ansistring;
begin
runcommand('ipconfig',['/all'],s);
writeln(s);
end.
工作正常,省去了很多麻烦。 (虽然 FPC 2.6.2+)
我想捕获 cmd.exe 输出并在我制作的不同图形用户界面中显示它。我想制作一个具有扩展功能的命令解释器。 dir 命令运行完美,当我尝试执行另一个进程如 ipconfig 时出现问题。
我没有看到 ipconfig 输出。有解决办法吗?!
我使用来自 Lazarus (FreePascal) 的 TProcess 组件
proc := TProcess.Create(nil);
proc.Options:= [poUsePipes, poNoConsole];
proc.ShowWindow:= swoHIDE;
proc.Executable:= 'cmd';
读取输出线程:
if (Length(cmd) > 0) then
begin
cmd := cmd + #13#10;
proc.Input.Write(cmd[1], Length(cmd)); // here I write command from user
strikes := 0;
end
else
if proc.Output.NumBytesAvailable > 0 then
begin
while proc.Output.NumBytesAvailable > 0 do
begin
FillChar(buf, sizeof(buf), #0);
proc.Output.Read(buf, sizeof(buf) - 1);
data := data + buf;
end;
// data gets echoed to user
它对我来说很好(我使用 FPC 3.1.1 和 Lazarus 1.5,但我希望它没关系):
proc.Options:= [poUsePipes];
proc.ShowWindow:= swoHIDE;
proc.Executable:= 'cmd';
...
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
cmd: String;
begin
if Key = #13 then
begin
Key := #0;
if not proc.Active then
proc.Active := True;
cmd := Edit1.Text + LineEnding;
proc.Input.Write(cmd[1], Length(cmd));
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
buf: array[0..65535] of Char;
begin
if proc.Output.NumBytesAvailable > 0 then
begin
while proc.Output.NumBytesAvailable > 0 do
begin
FillChar(buf, sizeof(buf), #0);
proc.Output.Read(buf, sizeof(buf) - 1);
Memo1.Lines.Add(buf);
end;
end;
end;
我猜你只是没有正确捕获进程输出。 祝你好运。
PS:如果您需要创建一些 windows 类似控制台的应用程序,我认为最好的方法是使用 Windows console API 而不是跨平台的 Lazarus 组件。
PPS:要使用 Lazarus 模拟控制台外观和行为,请使用 CmdLine 组件。
通常明智的做法是首先检查简短示例是否不能解决问题:
例如
uses process;
var s : ansistring;
begin
runcommand('ipconfig',['/all'],s);
writeln(s);
end.
工作正常,省去了很多麻烦。 (虽然 FPC 2.6.2+)