Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我不能通过代码获取ftp.exe的输出?_C#_Command Line - Fatal编程技术网

C# 为什么我不能通过代码获取ftp.exe的输出?

C# 为什么我不能通过代码获取ftp.exe的输出?,c#,command-line,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 =

我通过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()将一些输出写入其标准输出流。我用上面的代码测试它。它很好用。我就是不明白为什么上面的代码不能与ftp.exe一起工作?SimpleConsoleOutput程序与“ftp.exe”之间的唯一区别在于ftp.exe有自己的交互式命令提示符

(---------新进展----------------)

这是我个人调查的一些进展

我写了两个线程来写入StdIn,从“ftp.exe”的StdOut读取,输出如下:

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”的标准数据流。 这怎么可能??谢谢你的评论


我使用“ftp.exe”的其他命令进行了测试,除了“help”命令之外,这似乎很正常。我认为问题在于输出缓冲区尚未刷新,因此您无法从ftp命令获得完整的输出

当您发出“退出”命令时,您应该会看到help命令的输出

我还没有解决方案,但如果我发现有什么有用的,我会稍后再回来。

根据经验(我以前多次使用命令行FTP),您最好使用像这样的FTP插件

通过这种方式,您将完全控制FTP会话,能够向用户提供更好的反馈,并以适当的方式处理错误


最后一点,在处理FTP时,错误处理非常重要。

FTP.exe只是保持运行。由于ftp.exe没有结束,因此您无法进入“结束”部分 发出help命令时,它将显示提示并等待另一个命令

如果要读取命令的响应,则需要解析响应并查找新的提示。也就是说,当您再次看到像
ftp>
这样的行时,您得到了整个响应


(除非您有非常非常充分的理由使用ftp.exe,否则请改用FtpWebRequest类)

您是否尝试了
ReadLine
而不是
Read
来读取重定向的输出?

不担心您没有正确关闭进程,用于读取进程输出的代码应该如下所示:

 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.exe的输入和输出的原因是,来自Microsoft Windows 2000/XP/Vista的内置ftp.exe使用

这不仅仅是ftp程序不刷新其缓冲区的情况

如果将ftp.exe的调用替换为cmd.exe之类的调用,您将看到它工作正常。问题是您试图读取FTP未发送的输出。
不能使用常规方法读取和写入子ftp.exe。这是特定ftp.exe应用程序实现的结果


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

你的选择是:

  • 使用不同的ftp程序。他们可能不会像MS内置程序那样使用控制台I/O方法
  • 使用FTP类,如FtpWebRequest
  • 如果这不合适或不可能,请使用低级别的网络套接字接口进行FTP


另请参见:

我也这么认为,事实上,ftp.exe/help将输出到STDERR。然而,在交互模式下,输出到标准输出。啊,好吧,你每天都能学到一些东西我将编辑我的答案,但我仍然认为,将ftp.exe作为外部进程运行是处理ftp的一种糟糕方式。有太多的事情可能会出错,让它留给外部代码。是的,使用FTP库或
FtpWebRequest
类要好得多。就个人而言,我更喜欢.NET:)的RemObjects Internet Pack中的FtpClient。我决定使用edtFTP,因为这是我能找到的第一个免费的:-)谢谢,0xA3。“退出”命令可以是一种变通方法。但我只想知道ftp.exe和SimpleConsoleOutput.exe之间的区别。为什么后一个可以运行smootyly?@smwikipedia:我相信0xA3已经在回答中很好地解释了->“输出缓冲区还没有刷新”谢谢,没有。但是如果我不能到达“结束”部分,为什么我的程序在“帮助”命令输出的第一行之后停止?谢谢你的回答。是的,我试过ReadLine(),ReadToEnd()…没有一个能正确获得输出。谢谢你的回复。我将“help”命令写入StdIn,因为我想模拟“ftp.exe”的交互式命令提示符。你有没有试着检查一下标准输出的ftp文件,然后向标准输入发送“再见”?然后它应该转到WaitForExit调用,而不是仅仅等待更多的输入。非常感谢,Cheeso。我想知道ftp.exe的输出到底发送到哪里?有一个不可忽视的事实,我确实从标准输出中得到了“help”命令的输出,尽管经过了相当长的“延迟”…嗨,Cheeso,希望你能对我最后的担忧给我更多的评论。。。谢谢。其实我不知道;但是你想做什么呢?如果您想执行FTP操作,还有其他方法可以实现。为什么要限制你必须使用ftp.exe,当它被自动化时显然是不切实际的?嗨,Cheeso。我正在做一些关于斯坦的研究