Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I cannot get the output of ftp.exe by code?

I execute the ftp.exe cmd through a C# System.Diagnostics.Process type. And I use the following code to get the "ftp.exe" output after I programmatically enter a "help" command. But I can only get the first line of the result. And I never get to the "end" output part. The whole program seems blocked.

    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");

However, I write a simple program which only use Console.Writeline() to write some output to its StdOut stream. And I test it with the above code. It works fine. I just cannot figure out why the above code cannot work with ftp.exe? The only difference between my SimpleConsoleOutput program and the "ftp.exe" is that the ftp.exe has its own interactive command prompt.

(--------------- New Progress -----------------)

Here're some progress of my personal investigation.

I write 2 threads to write to the StdIn and read from StdOut of "ftp.exe", and the output is like this:

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
...

and the last commands list is not even complete.

It seems that the help command output is divided into two parts.

The 1st part is:

Commands may be abbreviated.  Commands are:

The 2nd part is:

!              delete          literal         prompt          send
?              debug           ls              put             status
append         dir             mdelete         pwd             trace
...

And all the 1st parts are wrtten to the StdOut stream of "ftp.exe" before all the 2nd parts. How coud this be?? Thanks for your comments.

I tested with other command of the "ftp.exe", and it seems normal except the "help" command

like image 699
smwikipedia Avatar asked Mar 29 '10 10:03

smwikipedia


1 Answers

The reason why you cannot get the input and output of ftp.exe is because the built-in ftp.exe from Microsoft Windows 2000/XP/Vista uses Console Input/Output.

It is not simply a case of the ftp program not flushing its buffers.

If you replace your invocation of ftp.exe with something like cmd.exe, you'll see that it works fine. The problem is you are trying to read output where FTP is not sending it.
You cannot use the regular approach to reading and writing to a child ftp.exe. This is a consequence of the implementation of that particular ftp.exe app.


If you truly need to automate the built-in Windows ftp program, you will need to resort to pinvoke and the ReadConsoleOutput win32 function.

Your alternatives are:

  • use a different ftp program. Likely they do not resort to the console I/O approach that the MS built-in program does
  • use an FTP class, like FtpWebRequest.
  • if that's not appropriate or possible, use a low level network socket interface to FTP.

see also: http://discuss.joelonsoftware.com/default.asp?design.4.332503.5

like image 147
Cheeso Avatar answered Sep 18 '22 02:09

Cheeso