2010-03-29 3 views
6

Я выполняю ftp.exe cmd через C# System.Diagnostics.Process. И я использую следующий код, чтобы получить вывод «ftp.exe» после того, как я программным образом введите команду «help». Но я могу получить только первую строку результата. И я никогда не добираюсь до конечной выходной части. Вся программа кажется заблокированной.Почему я не могу получить вывод ftp.exe по коду?

Process p = new Process(); 
    p.StartInfo.FileName = @"C:\Windows\System32\ftp.exe"; 
    p.StartInfo.CreateNoWindow = true; 
    p.StartInfo.RedirectStandardInput = true; 
    p.StartInfo.RedirectStandardOutput = true; 
    p.StartInfo.RedirectStandardError = true; 

    p.StartInfo.UseShellExecute = false; 
    p.Start(); 

    p.StandardInput.WriteLine("help"); 

    Int32 c_int = p.StandardOutput.Read(); 
    while (c_int != -1) 
    { 
     Char c = (Char)c_int; 
     Console.Write(c); 
     c_int = p.StandardOutput.Read(); 
    } 

    Console.WriteLine("end"); 

Однако, я пишу простую программу, которая только использовать Console.WriteLine(), чтобы написать некоторый вывод его поток STDOUT. И я тестирую его с помощью вышеуказанного кода. Он работает нормально. Я просто не могу понять, почему приведенный выше код не может работать с ftp.exe? Единственная разница между моей программой SimpleConsoleOutput и «ftp.exe» заключается в том, что ftp.exe имеет собственную интерактивную командную строку.

(--------------- Новый Progress -----------------)

Here're некоторый прогресс в мое личное расследование.

Я пишу 2 темы, писать в STDIN и считываемых из STDOUT из «ftp.exe», и выход, как это:

Commands may be abbreviated. Commands are: 

Commands may be abbreviated. Commands are: 

Commands may be abbreviated. Commands are: 
....(exactly 16 times of above lines and then exactly 16 times of the following cmds list) 
!    delete   literal   prompt   send 
?    debug   ls    put    status 
append   dir    mdelete   pwd    trace 
... 

и последний список команд даже не завершена.

Кажется, что вывод команды справки разделен на две части.

1-ая часть:

Commands may be abbreviated. Commands are: 

2-я часть:

!    delete   literal   prompt   send 
?    debug   ls    put    status 
append   dir    mdelete   pwd    trace 
... 

И все 1-й части wrtten в поток STDOUT из «ftp.exe» перед всеми 2-й части , Как это может быть ?? Спасибо за ваши комментарии.

я тестировал с другой командой «ftp.exe», и это кажется нормальным, кроме команды «помощи»

+0

Просто из интереса, почему вы так заинтересованы в выходе ftp.exe, если вы не собираетесь использовать его? – CResults

+1

Привет, CResults. Я изучаю стандартные потоки консольных приложений. И ftp.exe - одна из моих целей эксперимента. – smwikipedia

ответ

5

Причина почему вы не можете получить вход и выход из ftp.exe потому, что встроенный ftp.exe из Microsoft Windows 2000/XP/Vista использует Console Input/Output.

Это не просто случай, когда программа ftp не смывает свои буферы.

Если вы заменили ваш вызов ftp.exe чем-то вроде cmd.exe, вы увидите, что он отлично работает. Проблема в том, что вы пытаетесь прочитать вывод, где FTP не отправляет его.
Вы не можете использовать регулярный подход к чтению и записи дочернему ftp.exe. Это является следствием реализации этого конкретного приложения ftp.exe.


Если вы действительно нужно автоматизировать встроенный FTP программы Windows, вам нужно будет прибегнуть к PInvoke и функция ReadConsoleOutput win32.

Ваши альтернативы:

  • использовать другой FTP программы. Скорее всего, они не прибегают к консольному вводу-выводу, что встроенная в MS программа
  • использует класс FTP, например FtpWebRequest.
  • Если это не подходит или возможно, используйте интерфейс сетевого уровня низкого уровня для FTP.

Смотри также: http://discuss.joelonsoftware.com/default.asp?design.4.332503.5

+2

Большое спасибо, Cheeso. Мне интересно, куда именно передает ftp.exe свой вывод? Есть один факт, который нельзя игнорировать, я получаю вывод команды «help» из StdOut, хотя после довольно «латентности» ... – smwikipedia

+0

Привет, Cheeso, надеюсь, вы могли бы дать мне еще несколько комментариев о моей последней заботе. .. благодаря. – smwikipedia

+0

Я вообще не знаю; но что вы пытаетесь сделать? Если вы хотите выполнять FTP-операции, есть другие способы их выполнения. Почему ограничение, которое вы должны использовать ftp.exe, когда оно явно нецелесообразно при автоматическом режиме? – Cheeso

2

Я думаю, что проблема заключается в том, что выходной буфер еще не покраснел и, следовательно, вы не делаете получить полный вывод из команды ftp.

Когда вы выбрали команду «quit», вы должны увидеть выход команды справки.

У меня пока нет решения, но я вернусь позже, если найду что-нибудь полезное.

+0

Спасибо, 0xA3. команда «выйти» может быть обходным путем. Но я просто хочу знать разницу между ftp.exe и моим SimpleConsoleOutput.exe. Почему последний мог сглаживать? – smwikipedia

+0

@smwikipedia: Я считаю, что 0xA3 уже объяснил, что довольно хорошо в ответе -> «выходной буфер еще не очищен» –

0

Из опыта (я использовал FTP-соединение по нескольку раз раньше) вам было бы намного лучше использовать FTP-плагин, такой как этот Enterprise DT FTP.

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

Последний вопрос, обработка ошибок очень важна при работе с FTP.

+0

Я думал, что то же самое, и действительно, ftp.exe/help будет выводиться в STDERR. Однако в интерактивном режиме выход переходит в STDOUT. –

+0

Ahh ok, вы узнаете что-то каждый день! - Я отредактирую свой ответ, но я все же считаю, что запуск ftp.exe в качестве внешнего процесса - это плохой способ обработки FTP. Слишком много вещей, которые могут пойти не так, чтобы оставить его во внешнем коде. – CResults

+2

Да, гораздо лучше использовать библиотеку FTP или класс «FtpWebRequest». –

2

ftp.exe просто продолжает работать. Вы не дойдете до конца, так как ftp.exe не завершит при выдаче команды help, он представляет приглашение и ждет другую команду.

Если вы хотите прочитать ответ команды, вам нужно проанализировать ответ и искать новое приглашение.То есть, вы получили весь ответ, когда снова видите строку, такую ​​как ftp>.

(Если у вас нет очень, очень веские причины, чтобы использовать ftp.exe, используйте класс FtpWebRequest скорее)

+0

Спасибо, nos. Но если я не дойду до конца, почему моя программа останавливается сразу после выхода первой строки команды «help»? – smwikipedia

0

вы пробовали ReadLine вместо Read читать с перепрофилированием производства?

+0

Thansk для вашего ответа. Да, я пробовал ReadLine(), ReadToEnd() ... ни один из них не смог получить выход правильно. – smwikipedia

0

Мало обеспокоены тем, что вы не закрывая процесс должным образом, ваш код для чтения вывода из процесса должен выглядеть примерно так:

process.Start(); 

output = process.StandardOutput.ReadToEnd(); // read the output here... 

process.WaitForExit(); // ...then wait for exit, as after exit, it can't read the output 

returnCode = process.ExitCode; 

process.Close(); // once we have read the exit code, can close the process 

Не уверен, что если бы решить этот конкретный вопрос, хотя.

Кроме того, почему вы пишете «помощь» для стандартного ввода, он не работает, если вы

process.Arguments = "help"; 
+0

Спасибо за ваш ответ. Я пишу команду «help» для StdIn, потому что хочу эмулировать интерактивную командную строку «ftp.exe». – smwikipedia

+0

А я вижу. Вы пытались проверить stdout для '> ftp', а затем отправили «bye» в stdin? Затем он должен перейти к вызову WaitForExit вместо того, чтобы просто ждать большего ввода. –