Я завернул большую часть wininet без проблем, но теперь я застрял. Я пытаюсь p / invoke FtpCommand из wininet.dll, но каждая команда, которую я запускаю, выдает «Ошибка синтаксиса 500». Даже простые команды, такие как dir или ls. Если я подключаюсь к тому же серверу с помощью ftp.exe, команды работают нормально и возвращают ожидаемые результаты.
Вот определение метода:
[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);
И код, по которому я его называю:
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 "";
}
Все остальное работает, я могу загружать файлы, загружать файлы и имитировать команду dir, используя FtpFindFirstFile (), но я не могу отправить команды, используя описанный выше метод.
EDIT
Мой код для SendCommand только что был SendCommand ("DIR") или SendCommand ("LS"). Прочитав один из ответов (не вижу, кто во время редактирования), я изменил его на SendCommand («LIST»), и он успешно вернулся.
Однако у меня возник вопрос, как прочитать результат, что я использую для чтения данных, возвращаемых командой LIST, чтобы я мог вывести их в читаемом формате?
Я обновил метод SendCommand, чтобы показать, как я планирую читать возвращаемые данные, но я всегда получаю 0 для bytesRead. Я также попытался передать дескриптор, полученный dataSocket, в вызов FtpCommand, но приложение просто завершается без ошибок, если я это сделаю.
РЕДАКТИРОВАТЬ 2
Я использую InternetReadFile для чтения данных из дескриптора сокета данных, возвращенного при моем вызове FtpCommand. Подпись метода для InternetReadFile, которую я использую, такова:
[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);
ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ
Я выпустил этот код на codeplex :