我通过C#System.Diagnostics.Process类型执行ftp.exe cmd。在我以编程方式输入“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有自己的交互式命令提示符。
(---------------新进展-----------------)
以下是我个人调查的一些进展。
我写两个线程写入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
...
并且最后的命令列表甚至都没有完成。
似乎帮助命令输出分为两部分。
第一部分是:
Commands may be abbreviated. Commands are:
第二部分是:
! delete literal prompt send
? debug ls put status
append dir mdelete pwd trace
...
在所有第二部分之前,所有第一部分都在“ftp.exe”的StdOut流中。 这怎么样?感谢您的评论。
我使用“ftp.exe”的其他命令测试过,除了“help”命令外它似乎正常
答案 0 :(得分:5)
为什么无法获取ftp.exe的输入和输出的原因是因为Microsoft Windows 2000 / XP / Vista中的内置ftp.exe使用Console Input/Output。
这不仅仅是ftp程序没有刷新缓冲区的情况。
如果用cmd.exe替换你的ftp.exe调用,你会发现它工作正常。问题是你正在尝试读取FTP没有发送它的输出 您不能使用常规方法来读取和写入子ftp.exe。这是特定ftp.exe应用程序实现的结果。
如果您真的需要自动执行内置的Windows ftp程序,则需要使用pinvoke和ReadConsoleOutput win32函数。
您的替代方案是:
另见:http://discuss.joelonsoftware.com/default.asp?design.4.332503.5
答案 1 :(得分:2)
我认为问题是输出缓冲区尚未刷新,因此您无法从ftp命令获得完整输出。
当您发出“退出”命令时,您应该看到help命令的输出。
我还没有解决方案,但如果我发现任何有用的东西,我会稍后回来。
答案 2 :(得分:2)
ftp.exe一直在运行。你不会到达'结束'部分,因为ftp.exe没有结束 当您发出help命令时,它会显示一个提示并等待另一个命令。
如果要读取命令的响应,则需要解析响应并查找新提示。也就是说,当你再次看到ftp>
这样的行时,你得到了整个回复。
(除非你有非常好的理由使用ftp.exe,否则请使用FtpWebRequest类)
答案 3 :(得分:0)
根据经验(我以前曾多次使用过命令行FTP),使用像这样的Enterprise DT FTP这样的FTP插件会好得多。
通过这种方式,您可以完全控制FTP会话,能够为用户提供更好的反馈并以正确的方式应对错误。
最后一点,处理FTP时错误处理非常重要。
答案 4 :(得分:0)
您是否尝试过ReadLine
而不是Read
来读取重定向的输出?
答案 5 :(得分: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";