I've wrapped most of wininet with no problems, but now I'm stuck. I am trying to p/invoke FtpCommand from wininet.dll, but every command I run returns "500 syntax error". Even simple commands like dir, or ls. If I connect to the same server with ftp.exe the commands work fine and return expected results.
Here's the method definition:
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError=true)]
extern public static int FtpCommand(
[In] IntPtr hConnect,
[In] bool fExpectResponse,
[In] int dwFlags,
[In] string command,
[In] IntPtr dwContext,
[In][Out] ref int ftpCommand);
And the code where I'm calling it:
public string SendCommand(string cmd)
{
int result;
IntPtr dataSocket = new IntPtr();
switch(cmd)
{
case "PASV":
result = WININET.FtpCommand(_hConnect, false, WININET.FTP_TRANSFER_TYPE_ASCII, cmd, IntPtr.Zero, ref dataSocket);
break;
default:
result = WININET.FtpCommand(_hConnect, true, WININET.FTP_TRANSFER_TYPE_ASCII, cmd, IntPtr.Zero, ref dataSocket);
break;
}
Console.WriteLine(InternetLastResponseInfo());
int BUFFER_SIZE = 8192;
if(result == 0){
Error();
}
else if(dataSocket != IntPtr.Zero)
{
StringBuilder buffer = new StringBuilder(BUFFER_SIZE);
int bytesRead = 0;
do
{
result = WININET.InternetReadFile(dataSocket, buffer, BUFFER_SIZE, ref bytesRead);
} while (result == 1 && bytesRead > 1);
return buffer.ToString();
}
return "";
}
Everything else is working, I can download files, upload files and imitate the dir command using FtpFindFirstFile(), but I can't seem to send commands using the above method.
My code for SendCommand has just been SendCommand("DIR") or SendCommand("LS"). After reading one of the answers (can't see who while I'm editing) I changed it to SendCommand("LIST") and that returned successfully.
However, my question was how to read the result, what do I use to read the data returned from the LIST command, so that I can output it in a readable format?
I've updated the SendCommand method to show how I plan on reading the data returned, but I always get 0 for bytesRead. I've also tried passing the handle received by dataSocket in the FtpCommand call, but the app just exits with no errors if I do that.
I'm using InternetReadFile to read data from the handle of the data socket returned in my call to FtpCommand. The method signature for InternetReadFile I am using is this:
[DllImport("wininet.dll", CharSet = CharSet.Ansi, SetLastError = true)]
extern public static int InternetReadFile(
[In] IntPtr hConnect,
[In][Out] StringBuilder buffer,
[In] int buffCount,
[In][Out] ref int bytesRead);
I released this code on codeplex:
Why are you getting 500 Syntax error
s?
Remember that unlike an FTP client (like ftp.exe
) the actual FTP protocol doesn't take commands like ls
, it takes commands like LIST
and NLST
See the Raw FTP Command List or RFC 959 for a list of commands accepted by FTP
How do you get the results of a LIST
or NLST
command?
The last parameter to FtpCommand
is
A pointer to a handle that is created if a valid data socket is opened. The
fExpectResponse
parameter must be set toTRUE
forphFtpCommand
to be filled.
You can use this handle to read out the list with InternetReadFile
.
Notes:
ftp.exe
and compare it to what your code is sending