Почему я не могу получить вывод ftp.exe по коду? - PullRequest
6 голосов
/ 29 марта 2010

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

    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 есть собственная интерактивная командная строка.

(--------------- Новый прогресс -----------------)

Вот мой прогресс в личном расследовании.

Я пишу 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-ые части записываются в поток StdOut "ftp.exe" перед всеми 2-ыми частями. Как это может быть ?? Спасибо за ваши комментарии.

Я тестировал с другой командой "ftp.exe", и это выглядит нормально, кроме команды "help"

Ответы [ 6 ]

5 голосов
/ 02 апреля 2010

Причина , почему вы не можете получить ввод и вывод ftp.exe, заключается в том, что встроенный ftp.exe из Microsoft Windows 2000 / XP / Vista использует Консольный ввод / вывод .

Это не просто случай, когда программа 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 голосов
/ 29 марта 2010

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

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

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

2 голосов
/ 29 марта 2010

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

Когда вы запускаете команду "quit", вы должны увидеть результат команды help.

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

0 голосов
/ 29 марта 2010

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

 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 голосов
/ 29 марта 2010

Вы пробовали ReadLine вместо Read для чтения с перенаправленного выхода?

0 голосов
/ 29 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...