Я выполняю ftp.exe cmd через Систему C#. Диагностика. Тип процесса. И я использую следующий код для получения "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");
Однако я пишу простую программу, которые только используют Консоль. 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-е части являются wrtten к потоку StdOut "ftp.exe" перед всеми 2-ми частями. Как coud это быть?? Спасибо за Ваши комментарии.
Я протестировал с другой командой "ftp.exe", и это кажется нормальным кроме команды "справки"
Причина , почему вы не можете получить ввод и вывод ftp.exe обусловлен тем, что встроенный ftp.exe из Microsoft Windows 2000 / XP / Vista использует Консольный ввод / вывод .
Это не просто случай, когда ftp-программа не очищает свои буферы.
Если вы замените вызов ftp.exe чем-то вроде cmd.exe, вы увидите, что он работает нормально. Проблема в том, что вы пытаетесь прочитать вывод, который FTP не отправляет.
Вы не можете использовать обычный подход для чтения и записи дочернего ftp.exe. Это следствие реализации конкретного приложения ftp.exe.
Если вам действительно нужно автоматизировать встроенную программу ftp Windows, вам придется прибегнуть к pinvoke и функции win32 ReadConsoleOutput .
Ваши альтернативы:
см. Также: http://discuss.joelonsoftware.com/default.asp?design.4.332503.5
ftp.exe просто продолжает работать. Вы не дойдете до «конечной» части, поскольку ftp.exe не заканчивает , когда вы вводите команду справки, он выводит приглашение и ждет другой команды.
Если вы хотите прочитать ответ команды, вам нужно проанализировать ответ и найти новое приглашение. То есть вы получили полный ответ, когда снова видите строку типа ftp>
.
(Если у вас нет очень и очень веских причин для использования ftp.exe, лучше используйте класс FtpWebRequest)
Вы пробовали ReadLine
вместо Читать
для чтения из перенаправленного вывода?
Я думаю, что проблема в том, что выходной буфер еще не очищен, и, следовательно, вы не получаете полный вывод от команды ftp.
Когда вы выдаете команду "quit", вы должны увидеть выходные данные команды help.
У меня пока нет решения, но я вернусь позже, если найду что-то полезное.
Немного беспокоит то, что вы не закрываете процесс должным образом, ваш код для чтения вывода из процесса должен выглядеть примерно так:
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";
Исходя из опыта (я уже много раз пользовался командной строкой FTP), вам было бы намного лучше использовать плагин FTP, такой как этот Enterprise DT FTP .
Таким образом, вы получите полный контроль над своим FTP-сеансом, сможете улучшить обратную связь с вашим пользователем и правильно справиться с ошибками.
Последний пункт, обработка ошибок очень важна при работе с FTP.