为什么我无法通过代码获取ftp.exe的输出?

smw*_*dia 6 c# command-line

我通过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");
Run Code Online (Sandbox Code Playgroud)

但是,我编写了一个简单的程序,它只使用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
...
Run Code Online (Sandbox Code Playgroud)

并且最后的命令列表甚至没有完成.

似乎帮助命令输出分为两部分.

第一部分是:

Commands may be abbreviated.  Commands are:
Run Code Online (Sandbox Code Playgroud)

第二部分是:

!              delete          literal         prompt          send
?              debug           ls              put             status
append         dir             mdelete         pwd             trace
...
Run Code Online (Sandbox Code Playgroud)

在所有第二部分之前,所有第一部分都在"ftp.exe"的StdOut流中.这怎么样?感谢您的意见.

我用"ftp.exe"的其他命令测试过,除了"help"命令外似乎正常

Che*_*eso 5

究其原因,为什么你不能让输入和Ftp.exe的输出是因为从Microsoft Windows 2000/XP/Vista中内置Ftp.exe的使用控制台输入/输出.

这不仅仅是ftp程序没有刷新缓冲区的情况.

如果用cmd.exe之类的东西替换你的ftp.exe调用,你会发现它工作正常.问题是您正在尝试读取FTP未发送的输出.
您不能使用常规方法来读取和写入子ftp.exe.这是特定ftp.exe应用程序实现的结果.


如果您确实需要自动化内置的Windows ftp程序,则需要使用pinvoke和ReadConsoleOutput win32函数.

您的替代方案是:

  • 使用不同的ftp程序.可能他们没有采用MS内置程序所做的控制台I/O方法
  • 使用FTP类,如FtpWebRequest.
  • 如果这不合适或不可能,请使用FTP的低级网络套接字接口.

另见:http://discuss.joelonsoftware.com/default.asp?design.4.332503.5

  • 非常感谢Cheeso.我想知道ftp.exe到底输出的确切位置是什么?有一个事实是不可忽视的,我确实从StdOut得到了"help"命令的输出,虽然经过了相当多的"延迟"...... (2认同)