2015-03-13 5 views
0

Я хочу захватить вывод cmd.exe и показать его в отличном gui, который я создаю. Я хочу сделать командный интерпретатор с расширенной функциональностью. Команда dir работает безупречно, проблема возникает, когда я пытаюсь выполнить другой процесс, например ipconfig.Capture all commands output

Я не вижу выход ipconfig. Есть ли на этом рабочий стол?!

Я использую TProcess компонент из Lazarus (FreePascal)

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 
+0

Мы не можем видеть ваш код. –

+0

@DavidHeffernan Я использую TProcess из пакета lazarus, это флаги создания. Не думайте, что код неправильный – opc0de

+0

'proc.ShowWindow' не имеет никакой цели. Это консольное приложение, «poNoConsole» - это то, что важно. Если вы показали полную программу, которая поможет. –

ответ

1

Он отлично работает для меня (я использую 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; 

Я думаю, что вы просто не поймаете проце ss правильно. Удачи.

PS: Если вам нужно создать какое-то консольное приложение для Windows, лучшим способом, я думаю, является использование Windows console API вместо кросс-платформенных компонентов Lazarus.

PPS: Чтобы эмулировать внешний вид консоли и поведение с использованием Lazarus, используйте компонент CmdLine.

+0

удалил poNoConsole из процедуры создания компонентов и работает! Спасибо за помощь – opc0de

1

В целом это умно, чтобы сначала проверить, если короткие примеры не решают проблему:

например

uses process; 

var s : ansistring; 
begin 
    runcommand('ipconfig',['/all'],s); 
    writeln(s); 
end. 

прекрасно работает и экономит массу неприятностей. (FPC 2.6.2+, хотя)