Перенаправление стаута из дочернего процесса с помощью .net - PullRequest
3 голосов
/ 26 ноября 2008

Я использую следующий код

System::Diagnostics::Process^ p = gcnew System::Diagnostics::Process();
p->StartInfo->FileName =  "tnccmd.exe";
p->StartInfo->UseShellExecute = false;
p->StartInfo->RedirectStandardInput = true;
p->StartInfo->RedirectStandardOutput = true; 
p->Start();
System::IO::StreamWriter^ tnc_stdin = p->StandardInput;
System::IO::StreamReader^ tnc_stdout = p->StandardOutput;

tnc_stdin->WriteLine("connect i 127.0.0.1");
String^ prg_output = tnc_stdout->ReadToEnd();

Моя проблема в том, что я не могу правильно прочитать stdout. Однако я могу легко написать в stdin, но сейчас я пытаюсь реализовать код проверки ошибок, и он не работает.

Программа, которую я использую, похоже, не записывает в stdout, даже если она запускается из командной строки. Я могу воспроизвести bug с ftp.exe, который поставляется с Windows XP по умолчанию. Если вы измените ->FileName с помощью ftp.exe, командная строка ftp.exe обычно выдаст ftp>, не будет отображаться в prg_output.

Теперь я знаю, что в приглашении должен использоваться какой-то windows shell curses, и я могу перепутать проблемы.

Обычно только после connect i 127.0.0.1 инструкции, которую я должен получить connecting to 127.0.0.1..., но я ничего не получаю.

Любой намек на то, что я делаю не так? Есть ли другой тип stdout, о котором я не знаю?

EDIT

Я не могу использовать аргументы, потому что мне нужно написать несколько строк, очень похоже на ftp.exe. Кроме того, ftp.exe выводит, когда вы набираете такие команды, как dir. По крайней мере, он выводит, когда вы пишете неизвестные команды, он жалуется на Invalid command.

Ответы [ 4 ]

0 голосов
/ 06 сентября 2013

См. Этот пост в блоге о получении как стандартных Out, так и Err из управляемых приложений. CLR очень легко делает не то, что нужно, и блокирует себя.

Как правильно использовать System.Diagnostics.Process

0 голосов
/ 26 ноября 2008

возможно это проблема с буферизацией.

Что произойдет, если вы попытаетесь сбросить tnc_stdin? попробуйте что-то вроде этого:

tnc_stdin->WriteLine("connect i 127.0.0.1");
tnc_stdin->Flush();

Редактировать: Проверен ctor используемого StreamWriter (правила Reflector!) Согласно этому, размер буфера по умолчанию составляет 1024 байта ... так что вам нужно очистить :-) или вы можете определить меньший буфер.

    public StreamWriter(string path) : 
this(path, false, new UTF8Encoding(false, true), 0x400)
    {
    }
0 голосов
/ 10 апреля 2009

Я думаю, что вы забыли позвонить BeginOutputReadLine

0 голосов
/ 26 ноября 2008

Я подозреваю, что вы пытаетесь отправить в stdin то, что на самом деле должно быть аргументом командной строки. Как бы вы обычно вызывали tnccmd.exe? Как то так?

tnccmd.exe connect i 127.0.0.1

Если это так, то "connect i 127.0.0.1" не должен идти на стандартный ввод, а должен передаваться через p-> StartInfo-> Arguments.

(Проблема с ftp.exe не в вашей программе, а в самом ftp.exe, который выясняет, является ли его стандартный вывод консолью. Если его вывод отсутствует на консоли, он не выводит " ftp> "приглашение. Также возможно, что программа, которую вы пытаетесь написать, делает то же самое.)

...