使用Win32 API FTP

由於使用NET FTP 會出現中文檔名下載回來後變亂碼的問題,因此改用WIN32的API來完成檔案的上傳下載及查詢

using System.Runtime.InteropServices;

#region"定義API"
//產生Internet Session(InternetOpen)
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr InternetOpen(string strAppName, ulong
ulAccessType, string strProxy, string strProxyBypass, ulong ulFlags);

//產生FTP、HTTP...(InternetConnect)
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr InternetConnect(IntPtr ulSession, string strServer,
uint ulPort, string strUser, string strPassword, uint ulService, uint ulFlags, uint ulContext);

//關閉Internet Session(InternetClose)
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int InternetCloseHandle(ulong hInet);

//FTP上傳檔案
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool FtpPutFile(IntPtr ulSession, string strLocalFile,
string strServerFile, ulong ulFlags, ulong ulContext);

//FTP下載檔案
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool FtpGetFile(IntPtr ulSession, string strServerFile,
string strLocalFile, bool bolFailIfExist, ulong ulFlags, ulong ulInetFals, ulong ulContext);

//FTP刪除檔案
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool FtpDeleteFile(IntPtr ulSession, string strDelFile);

//瀏覽FTP伺服器目錄
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool FtpGetCurrentDirectory(IntPtr ulSession, string strDirPath, ref ulong ulBuffLength);

//建立目錄
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool FtpCreateDirectory(IntPtr ulSession, string strCreateDirectoryName);

//查找文件或目錄
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr FtpFindFirstFile(IntPtr hFtp, string lpszSearchFile, 
ref WIN32_FIND_DATA lpFindFileData, int dwFlags, int dwContext);

//移到下一個文件或目錄是否存在
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetFindNextFile(IntPtr ulFindFirst, ref WIN32_FIND_DATA lpFindFileData);

//改變目前資料夾
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool FtpSetCurrentDirectory(IntPtr ulSession, string strChangeDirectory);

//取得最號一個錯誤訊息
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetLastError();

//查找文件或目錄回傳值定義
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WIN32_FIND_DATA
{
    public int dwFileAttributes;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTme;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
    public int nFileSizeHigh;
    public int nFileSizeLow;
    public int dwReserved0;
    public int dwReserved1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string cFileName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
    public string cAlternate;
}

const ulong INTERNET_OPEN_TYPE_PRECONFIG = 0;//預設proxy伺服器設定為主
const uint INTERNET_DEFAULT_FTP_PORT = 21;//設定internet服務之通訊port
const uint INTERNET_SERVICE_FTP = 1;//設定internet服務類型
const uint INTERNET_FLAG_NO_CACHE_WRITE = 0x4000000;//不將Internet連結資訊寫入快取(noncache)
const uint INTERNET_FLAG_PASSIVE = 0x800000;
const bool PassiveConnection = true;
const ulong FTP_TRANSFER_TYPE_UNKNOWN = 0x0;//預設使用Binary模式
const ulong FTP_ATTRIBUTE_DIRECTORY = 0x10;//判斷是否是資料夾
IntPtr hSession;
IntPtr hOpen;
IntPtr hFind;
#endregion

宣告完畢以後就可以進行實際操作了

留言