一个完整的WINCE C# FTP客户端类,
致谢:
感谢优快云 accessysq 以及长期以来帮助我的阿飞专家。
/// <summary>
///
/// </summary>
public static class APIs
{
// service types for InternetOpen()
public enum ACCESS_TYPE_FOR_INTERNETOPEN
{
INTERNET_OPEN_TYPE_PRECONFIG = 0, // use registry configuration
INTERNET_OPEN_TYPE_DIRECT = 1, // direct to net
INTERNET_OPEN_TYPE_PROXY = 3, // via named proxy
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4 // prevent using java/script/INS
};
// service types for InternetConnect()
public enum ACCESS_TYPE_FOR_INTERNETCONNECT
{
INTERNET_SERVICE_FTP = 1,
INTERNET_SERVICE_GOPHER = 2,
INTERNET_SERVICE_HTTP = 3
};
// protocol-specific flags.
public enum PROTOCOL_SPECIFIC_FLAG
{
INTERNET_FLAG_PASSIVE = 0x08000000 // used for FTP connections
};
// These are the generic rights.
public enum ACCESS_TYPE_FOR_FILE : uint
{
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_ALL = 0x10000000
};
// FTP manifests
public enum ACCESS_TYPE_FOR_TRANSFER
{
FTP_TRANSFER_TYPE_UNKNOWN = 0x00000000,
FTP_TRANSFER_TYPE_ASCII = 0x00000001,
FTP_TRANSFER_TYPE_BINARY = 0x00000002
};
public enum FILE_ATTRIBUTE : uint
{
FILE_ATTRIBUTE_READONLY = 0x00000001,
FILE_ATTRIBUTE_HIDDEN = 0x00000002,
FILE_ATTRIBUTE_SYSTEM = 0x00000004,
FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
FILE_ATTRIBUTE_INROM = 0x00000040,
FILE_ATTRIBUTE_NORMAL = 0x00000080,
FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
MODULE_ATTR_NOT_TRUSTED = 0x00000200,
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
MODULE_ATTR_NODEBUG = 0x00000400,
FILE_ATTRIBUTE_COMPRESSED0x00000800,
FILE_ATTRIBUTE_OFFLINE0x00001000,
FILE_ATTRIBUTE_ROMSTATICREF = 0x00001000,
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
FILE_ATTRIBUTE_ROMMODULE = 0x00002000,
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
};
[DllImport("wininet.dll")]
public static extern int InternetOpen(string lpszCallerName, int dwAccessType, string lpszProxyName, string lpszProxyBypass, int dwFlags);
[DllImport("wininet.dll")]
public static extern int InternetConnect(int hInternetSession, string lpszServerName, int nProxyPort, string lpszUsername, string lpszPassword, int dwService, int dwFlags, int dwContext);
[DllImport("wininet.dll", CharSet = CharSet.Auto)] //CharSet.Ansi
public static extern int FtpFindFirstFile(int hConnect, string lpszSearchFile, [In, Out] FileData dirData, ulong ulFlags, ulong ulContext);
[DllImport("wininet.dll")]
public static extern int FtpGetFile(int hConnect, string lpszRemoteFile, string lpszNewFile, int fFailIfExists, int dwFlagsAndAttributes, uint dwFlags, int dwContext);
[DllImport("wininet.dll")]
public static extern bool FtpDeletefile(int hConnect, string lpszFileName);
[DllImport("wininet.dll")]
public static extern int InternetCloseHandle(int hInet);
[DllImport("wininet.dll")]
public static extern int FtpPutFile(int hConnect, string lpszLocalFile, string lpszNewRemoteFile, uint dwFlags, int dwContext);
[DllImport("wininet.dll", CharSet = CharSet.Auto)] //CharSet.Ansi
public static extern int FtpSetCurrentDirectoryA(int hConnect, string lpszDirectory);
[DllImport("wininet.dll", CharSet = CharSet.Auto)] //CharSet.Ansi
public static extern int InternetFindNextFileA(int hFind, [In, Out]FileData lpvFindData);
[DllImport("wininet.dll", CharSet = CharSet.Auto)] //CharSet.Ansi
public static extern int FtpOpenFile(int hConnect, string lpszFileName, ACCESS_TYPE_FOR_FILE dwAccess, ACCESS_TYPE_FOR_TRANSFER dwFlags, UInt32 dwContext);
[DllImport("wininet.dll", CharSet = CharSet.Auto)] //CharSet.Ansi
public static extern bool InternetWriteFile(IntPtr hFile, byte[] lpBuffer, UInt32 dwNumberOfBytesToWrite, ref Int32 lpdwNumberOfBytesWritten);
[DllImport("wininet.dll", CharSet = CharSet.Auto)] //CharSet.Ansi
public static extern bool InternetReadFile(IntPtr hFile, byte[] lpBuffer, int dwNumberOfBytesToRead, ref Int32 lpdwNumberOfBytesRead);
[DllImport("coredll.dll")]
public static extern uint GetLastError();
}
/// <summary>
///
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] //CharSet.Ansi
public class FileData
{
public int fileAttributes = 0;
public int creationTime_lowDateTime = 0;
public int creationTime_highDateTime = 0;
public int lastAccessTime_lowDateTime = 0;
public int lastAccessTime_highDateTime = 0;
public int lastWriteTime_lowDateTime = 0;
public int lastWriteTime_highDateTime = 0;
public int nFileSizeHigh = 0;
public int nFileSizeLow = 0;
public int dwReserved0 = 0;
public int dwReserved1 = 0;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public String fileName = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public String alternateFileName = null;
}
public class FtpOperator
{
private static List<FolderInfo> ListSubDir = null;
private static List<string> ListSubFile = null;
/// <summary>
///
/// </summary>
public struct FolderInfo
{
public string FolderName;
public string FolderPath;
public int Level;
}
/// <summary>
///
/// </summary>
/// <param name="ftpFile"></param>
/// <returns></returns>
public bool FtpFileExist(String ftpFile)
{
//变量声明
bool result = false;
int lnghInet = 0;
int lnghConnect = 0;
try
{
//初期化FTP的连接
lnghInet = APIs.InternetOpen("FtpOperator", 1, null, null, 0);
//连接FTP
lnghConnect = APIs.InternetConnect(lnghInet, "192.168.0.1", 21, "UserName", "Password", 1, 0, 0);
//结果的判断
if (lnghInet == 0 || lnghConnect == 0)
{
result = false;
return result;
}
//FTP文件查询
FileData foundData = new FileData();
int hFind = APIs.FtpFindFirstFile(lnghConnect, ftpFile, foundData, 0x80000000, 0);
//查询结果判断
if (hFind != 0)
{
result = true;
}
else
{
result = false;
}
}
catch (Exception ex)
{
Console.WriteLine("FtpFileExist Error:" + ex.Message);
result = false;
return result;
}
finally
{
//FTP连接关闭
if (lnghInet != 0)
{
APIs.InternetCloseHandle(lnghInet);
}
//FTP连接关闭
if (lnghConnect != 0)
{
APIs.InternetCloseHandle(lnghConnect);
}
}
//返回执行结果
return result;
}
/// <summary>
///
/// </summary>
/// <param name="ftpFileFullName"></param>
/// <param name="localFileFullName"></param>
/// <returns></returns>
public bool FtpFileDownLoad(string ftpFileFullName, string localFileFullName)
{
try
{
//初期化FTP的连接
int lnghInet = APIs.InternetOpen("FtpOperator", 1, null, null, 0);
//连接FTP
int lnghConnect = APIs.InternetConnect(lnghInet, "192.168.0.1", 21, "UserName", "Password", 1, 0, 0);
//取得指定文件
long ret = APIs.FtpGetFile(lnghConnect, ftpFileFullName, localFileFullName, 0, 0x80, 0x80000000, 0);
//判断执行结果
if (ret == 0)
{
return false;
}
//关闭连接
APIs.InternetCloseHandle(lnghInet);
APIs.InternetCloseHandle(lnghConnect);
}
catch
{
return false;
}
//返回结果
return true;
}
/// <summary>
///
/// </summary>
/// <param name="localFilePath"></param>
/// <returns></returns>
public bool FtpFileUpLoad(string localFileFullName)
{
try
{
//设定上传文件在FTP上的保存路径和名称
string ftpUpFullName = "/123.txt";
//检查本地文件是否存在
if (File.Exists(localFileFullName) == false)
{
return false;
}
//初始FTP连接
int lnghInet = APIs.InternetOpen("FtpOperator", 1, null, null, 0);
//连接FTP
int lnghConnect = APIs.InternetConnect(lnghInet, "192.168.1.108", 21, "czpf", "czpf", 1, 0, 0);
//打开ftp的文件
int hOpen = APIs.FtpOpenFile(lnghConnect, ftpUpFullName, APIs.ACCESS_TYPE_FOR_FILE.GENERIC_WRITE, APIs.ACCESS_TYPE_FOR_TRANSFER.FTP_TRANSFER_TYPE_BINARY, 0);
//读取本地文件到Buf
UInt32 idwNumberOfBytesToWrite = 0;
int ilpdwNumberOfBytesWritte = -1;
FileStream fs2 = new FileStream(@localFileFullName, FileMode.Open, FileAccess.Read, FileShare.Read);
idwNumberOfBytesToWrite = (UInt32)fs2.Length;
byte[] dataByte = new byte[idwNumberOfBytesToWrite];
fs2.Read(dataByte, 0, (int)idwNumberOfBytesToWrite);
fs2.Close();
//1、申请一段非托管的内存空间
//IntPtr hglobal = System.Runtime.InteropServices.Marshal.AllocHGlobal(dataByte.Length);
//2、将数据byte[]复制到这段内存空间
//System.Runtime.InteropServices.Marshal.Copy(dataByte, 0, hglobal, dataByte.Length);
//文件上传
bool ret = APIs.InternetWriteFile((IntPtr)hOpen, dataByte, idwNumberOfBytesToWrite, ref ilpdwNumberOfBytesWritte);
//long ret = APIs.FtpPutFile(lnghConnect, localFileFullName, ftpUpFullName, 0x80000000, 0);
//上传结果的判断
if (ret==false)
{
return false;
}
//关闭FTP的连接
APIs.InternetCloseHandle(lnghInet);
APIs.InternetCloseHandle(lnghConnect);
}
catch
{
return false;
}
//返回结果
return true;
}
public bool FtpDirDownLoad(string sourceFolder, string destFolder)
{
//定义变量
bool result = false;
int lnghInet = 0;
int lnghConnect = 0;
ListSubDir = null;
ListSubFile = null;
try
{
//初始化FTP的连接
lnghInet = APIs.InternetOpen("FtpOperator", 1, null, null, 0);
//连接FTP
lnghConnect = APIs.InternetConnect(lnghInet, "192.168.0.1", 21, "UserName", "Password", 1, 0, 0);
//连接结果判断
if (lnghInet == 0 || lnghConnect == 0)
{
return false;
}
//查询最初的文件夹的内容
GetFolderContent(lnghConnect, sourceFolder, 0);
//通过循环,取得子文件夹下面所有的内容
if (ListSubDir != null)
{
int currentLevel = 0;
int stopIndex = 0;
int currentDirLength0 = 0;
int currentDirLength1 = 0;
int currentFileLength0 = 0;
int currentFileLength1 = 0;
bool findExist;
FolderInfo fi;
while (true)
{
findExist = false;
stopIndex = ListSubDir.Count;
currentDirLength0 = ListSubDir == null ? 0 : ListSubDir.Count;
currentFileLength0 = ListSubFile == null ? 0 : ListSubFile.Count;
for (int i = 0; i < stopIndex; i++)
{
fi = ListSubDir[i];
if (fi.Level == currentLevel)
{
GetFolderContent(lnghConnect, fi.FolderPath, currentLevel + 1);
}
}
currentDirLength1 = ListSubDir == null ? 0 : ListSubDir.Count;
currentFileLength1 = ListSubFile == null ? 0 : ListSubFile.Count;
//.通过文件夹和文件的List的长度,判断是否取得到新的文件或文件夹
if (currentDirLength0 != currentDirLength1 || currentFileLength0 != currentFileLength1)
{
findExist = true;
}
else
{
findExist = false;
}
//.如果没有取到,则退出;否则,继续循环
if (findExist == false)
{
break;
}
else
{
currentLevel++;
}
}
//在本地建立从FTP取到的子文件夹
result = CreateFtpFolder(ListSubDir, destFolder);
//如果文件夹建立成功,从FTP取得所有文件
if (result == true)
{
result = CreateFtpFile(lnghConnect, ListSubFile, destFolder);
}
}
}
catch (Exception ex)
{
Console.WriteLine("FtpDirDownLoad Error:" + ex.Message);
result = false;
return result;
}
finally
{
//连接关闭
if (lnghInet != 0)
{
APIs.InternetCloseHandle(lnghInet);
}
//连接关闭
if (lnghConnect != 0)
{
APIs.InternetCloseHandle(lnghConnect);
}
}
//返回结果
return result;
}
/// <summary>
/// 取得指定FTP目录下所有的文件和文件夹
/// </summary>
/// <param name="connect"></param>
/// <param name="source"></param>
/// <param name="level"></param>
private void GetFolderContent(int connect, string source, int level)
{
//初始化变量
if (ListSubDir == null)
{
ListSubDir = new List<FolderInfo>();
}
//初始化变量
if (ListSubFile == null)
{
ListSubFile = new List<string>();
}
//变量定义
FileData foundData = new FileData();
int hFind = 0;
//改变FTP当前文件夹
int rst = APIs.FtpSetCurrentDirectoryA(connect, source);
//判断文件夹定位是否成功
if (rst != 0)
{
hFind = APIs.FtpFindFirstFile(connect, "*.*", foundData, 0x80000000, 0);
//检索文件的结果判断
if (hFind != 0)
{
do
{
//如果是文件夹的时候
if (foundData.fileAttributes == 16)
{
FolderInfo fi = new FolderInfo();
fi.FolderName = foundData.fileName.TrimEnd('/') + "/";
fi.FolderPath = source.TrimEnd('/') + "/" + foundData.fileName.TrimEnd('/') + "/";
fi.Level = level;
ListSubDir.Add(fi);
}
else
{
ListSubFile.Add(source.TrimEnd('/') + "/" + foundData.fileName);
}
}
while (APIs.InternetFindNextFileA(hFind, foundData) != 0);
}
else
{
return;
}
if (hFind != 0)
{
APIs.InternetCloseHandle(hFind);
}
}
else
{
return;
}
}
/// <summary>
/// 在本地建立从FTP上取得的文件夹
/// </summary>
/// <param name="source"></param>
/// <param name="dest"></param>
/// <returns></returns>
private bool CreateFtpFolder(List<FolderInfo> source, string dest)
{
if (source == null || source.Count == 0)
{
return true;
}
try
{
string path = null;
foreach (FolderInfo fi in source)
{
path = fi.FolderPath;
if (path == null || path.Trim() == "")
{
continue;
}
path = path.Trim('/').Replace("/", "\\");
path = Path.Combine(dest, path);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
}
catch (Exception ex)
{
Console.WriteLine("CreateFTPFolder Error:" + ex.Message);
return false;
}
return true;
}
/// <summary>
/// 在本地建立从FTP上取得的文件
/// </summary>
/// <param name="connect"></param>
/// <param name="source"></param>
/// <param name="dest"></param>
/// <returns></returns>
private bool CreateFtpFile(int connect, List<string> source, string dest)
{
if (source == null || source.Count == 0)
{
return true;
}
try
{
string path = null;
foreach (string s in source)
{
path = s;
if (path == null || path.Trim() == "")
{
continue;
}
path = path.Trim('/').Replace("/", "\\");
path = Path.Combine(dest, path);
//检查路径是否存在
if (Directory.Exists(Path.GetDirectoryName(path)) == false)
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
}
APIs.FtpGetFile(connect, s, path, 0, 0x80, 0x80000000, 0);
}
}
catch (Exception ex)
{
Console.WriteLine("CreateFtpFile:" + ex.Message);
return false;
}
return true;
}
}