我已经包装了大部分 wininet,没有任何问题,但现在我被卡住了。我正在尝试从 wininet.dll p/invoke FtpCommand,但我运行的每个命令都返回“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 "";
}
其他一切正常,我可以下载文件、上传文件并使用 FtpFindFirstFile() 模拟 dir 命令,但我似乎无法使用上述方法发送命令。
编辑
我的 SendCommand 代码是 SendCommand("DIR") 或 SendCommand("LS")。在阅读了其中一个答案后(在我编辑时看不到谁),我将其更改为 SendCommand("LIST") 并成功返回。
但是,我的问题是如何读取结果,我用什么来读取从 LIST 命令返回的数据,以便以可读的格式输出?
我更新了 SendCommand 方法以显示我计划如何读取返回的数据,但对于 bytesRead,我总是得到 0。我也尝试在 FtpCommand 调用中传递 dataSocket 接收的句柄,但如果我这样做,应用程序只会退出而没有错误。
编辑 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);