FTP - hur man använder det i VB
Förord
Översatt av Sven Persson, en artikel skriven av Av Joacim Andersson I ett projekt jag nyligen arbetade med,var jag tvungen till att lägga till support för FTP. Därför adderade jag Internet Transfer Control(INet till projektet). Jag fann snart att denna kontroll,som är utmärkt när du vill använda HTTP, inte fungerade så bra med FTP. Åtminstone inte om du kopplade upp dig till en FTP-server som inte körde under Windows NT eller Windows 2000. Jag beslutade mig för att skriva min egen "wrapper class" omkring FTP. Jag sökte genom MSDN bilioteket och fann en mängd funktioner för detta ändamål. De flesta hade namn som Ftp... någonting, tex.FtpPutFile, FtpGetFile, FtpCreateDirectory, osv. Alla funktioner krävde en "handler" till en FTP session.Efter en del grävande fann jag InternetConnect funktionen som kunde öppna en IP port för en speciell service (i detta fall FTP) och returnera en "handler" för denna service. Den krävde en "handler" till en öppnad Internet-session, som returneras av en funktion som kallas InternetOpen. Så "voila" för att kunna använda någon av FTP funktionerna behövde jag bara kalla InternetOpen följt av InternetConnect.Vi måste också städa upp efter oss, (min mor påpekade alltid detta). Därför när vi är klara med våra "handler" så måste vi kalla på "städpatrullen" InternetCloseHandle.Vi måste göra detta två gånger. Först för att stänga vår FTP-session "handler" och sedan stänga vår Internet-session "handler".Innehåll
»»
»
»
»
Turordning för detta är följande: Det finns fyra grundläggande steg vi måste utföra för att använda några av FTP funktionerna.
Låt oss titta på FtpGetFile funktionen för att ladda hem en fil från FTP-server. FtpGetFile funktionen ser ut så här med VB-specifica declarationer:
Vi behöver också InternetOpen och InternetConnect
funktionerna , så här blir det i VB:
Hämta Internet connection
Den första parametern (sAgent) specifierar applikationens "call" till funktionen, så vi skickar “MyFTPClient”. Den andra parametern (nAccessType) kan ta tre olika värde (0 , 1 eller 3)
och specefikt om vi använder en proxyserver eller inte. Om vi skickar 1 så ansluter vi direkt till Net. 3 betyder att vi använder en proxy och i detta fall skall vi skicka proxy namn till sProxyName parametern och någon proxy bypass information i sProxyBypass parameter.
Som ni ser så skickar jag här 0,vilket betyder att InternetOpen skall erhålla proxyinformation från registret.( "setting" som för Internet Explorer). Eftersom vi inte använder någon proxyserver,eller låter funktionen hämta denna information från registret så skickar vi vbNullString till 3:e och 4:e argumentet.
Den sista parametern (dwFlags) används för att indikera skillnader i funktionens uppträdande .Vi använder inte några av dessa ,vi skickar 0. Om funktionen fungerar felfritt kommer den att returnera ett icke 0 värde till varabeln hINetSession. Detta är "handlern" vi behöver för att gå vidare.
Skapa en FTP uppkoppling (anslut till värd/host)
Den första parametern som skickas till InternetConnect är den vi skapade här ovan hINetSession.Den andra är URL eller IP adress till den värd/host som vi vill ansluta oss till.(Obs använd inte ftp:// delen här,vi kommer att tala om för funktionen vilken service vi vill ha).
Nästa parameter är IP-port som skall användas.Jag skickar 21 här, men du kan lika gärna skicka 0,som talar om för funktionen att vi vill använda den defaulta porten för protokollet (21 är FTP protokoll).Därefter skickar vi "UserName och password".Vi loogar in som anonym och "password som Guest ".Nästa skickar vi ett värde som talar om för InternetConnect vilken service vi önskar.Jag använde en namngiven konstant INTERNET_SERVICE_FTP som är samma som 1.
Du kan använda vilken du vill av dessa här nedan.
Men i vårt fall är vi bara intresserade av FTP. Du kan också skicka värde 0 som argument. Då får funktionen själv lista ut vilken service vi är intresserade av. I det fallet måste vi skriva in det kompletta URL i sServerName parametern tex. (FTP://ftp.microsoft.com). Nästa dwFlags parameter till vilken vi kunde ha skickat &H8000000 (INTERNET_FLAG_PASSIVE) om vi önskat oss passiv FTP semantik. I detta exempel skickar vi helt enkelt 0. Sista parametern (dwContext) är ett användare-definierad värde som identifierar applikationen ifall vi vill använda "callbacks". Vi använder inga callbacks i detta exempel så vi skickar 0.
Anropa FTP funktionen ( FtpGetFile funktion)
Först så måste vi deklarera funktionen :
Sen är det bara att anropa den :
Först skickar vi hSession som vi fick från anropet till InternetConnect. Sedan namnet och som option sökvägen till filen vi vill komma åt,i detta exempel dirmap.htm.Tredje parametern är den lokala sökvägen och namn. fFailIfExists argumentet bestämmer hur funktionen skall reagera om den lokala
filen redan finns.Vi skickar False som betyder "skriv över gamla filen".
Sedan kommer dwFlagsAndAttributes parametern sätter attribut på lokala filen.Vi sätter inga attribut ,skickar 0. Sedan dwFlags parametern bestämmer hur filen kommer att transporteras 1 = ASCII, 2 = Binary. Sista parametern, igen är callbacks ,vi använder inte den 0.
Stänga handlerna (Städa up)
Vi stänger dem i omvänd ordning dvs hSession före hINetSession. För stänga handlerna så är det enda vi behöver gör är att skicka dem till InternetCloseHandle funktionen, som deklareras i VB så här .
Vi startar städningen :
Det var det hela vi har avverkat de fyra stegen och transfererat en fil från Microsoft till vår lokala hårddisk med hjälp av FTP.
Nu när vi vet hur man får tag i en fil,hur gör man för att lägga upp en fil på servern.? Det är lika enkelt som det ovan beskrivet.Vi behöver gå genom samma fyra steg.Skaffa en Internet connection "handle",och en FTP connection handle. Anropa FtpPutFile funktionen och sedan stänga ner våra "handlers".
FtpPutFile funktion deklareras så här :
Först skicka FTP session handle (den som returneras från InternetConnect funktion) sedan namnet och sökväg för den lokala filen. Sedan dwFlags parametern bestämmer hur filen kommer att transporteras 1 = ASCII, 2 = Binary. Sista parametern, igen är callbacks ,vi använder inte den 0.
Det här anropet kan misslyckas om vi inte har tillstånd att transferera till FTP servern
Det fins också en funktion för att ta bort en fil "Delete" :
Samma teknik som beskrivits innan, du kan få fel om du inte har tillstånd att utföra "Delete"
Så här kan du döpa om en fil :
Samma som kommentar i föregående funktion
- Starta en Internet anslutning genom att kalla på InternetOpen.
- Anslut till värden(host) genom att kalla på InternetConnect.
- Kalla på någon av FTP funktionerna.
- Stäng "handler" som tillverkades under steg 1 och 2
Låt oss titta på FtpGetFile funktionen för att ladda hem en fil från FTP-server. FtpGetFile funktionen ser ut så här med VB-specifica declarationer:
Private Declare Function FtpGetFile _
Lib "wininet.dll" Alias "FtpGetFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
Vi behöver också InternetOpen och InternetConnect
funktionerna , så här blir det i VB:
Private Declare Function InternetOpen _
Lib "wininet.dll" Alias "InternetOpenA" ( _
ByVal sAgent As String, _
ByVal nAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal nFlags As Long) As Long
Private Declare Function InternetConnect _
Lib "wininet.dll" Alias "InternetConnectA" ( _
ByVal hInternetSession As Long, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUserName As String, _
ByVal sPassword As String, _
ByVal nService As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Long
Detaljer om de fyra stegen
Steg1
Hämta Internet connection
hINetSession = InternetOpen(“MyFTPClient”, 0, vbNullString, vbNullString, 0)
Den första parametern (sAgent) specifierar applikationens "call" till funktionen, så vi skickar “MyFTPClient”. Den andra parametern (nAccessType) kan ta tre olika värde (0 , 1 eller 3)
och specefikt om vi använder en proxyserver eller inte. Om vi skickar 1 så ansluter vi direkt till Net. 3 betyder att vi använder en proxy och i detta fall skall vi skicka proxy namn till sProxyName parametern och någon proxy bypass information i sProxyBypass parameter.
Som ni ser så skickar jag här 0,vilket betyder att InternetOpen skall erhålla proxyinformation från registret.( "setting" som för Internet Explorer). Eftersom vi inte använder någon proxyserver,eller låter funktionen hämta denna information från registret så skickar vi vbNullString till 3:e och 4:e argumentet.
Den sista parametern (dwFlags) används för att indikera skillnader i funktionens uppträdande .Vi använder inte några av dessa ,vi skickar 0. Om funktionen fungerar felfritt kommer den att returnera ett icke 0 värde till varabeln hINetSession. Detta är "handlern" vi behöver för att gå vidare.
Steg 2
Skapa en FTP uppkoppling (anslut till värd/host)
hSession = InternetConnect(hINetSession, “ftp.microsoft.com”,
“21”, “anonymous”, “guest”, INTERNET_SERVICE_FTP, 0, 0)
Den första parametern som skickas till InternetConnect är den vi skapade här ovan hINetSession.Den andra är URL eller IP adress till den värd/host som vi vill ansluta oss till.(Obs använd inte ftp:// delen här,vi kommer att tala om för funktionen vilken service vi vill ha).
Nästa parameter är IP-port som skall användas.Jag skickar 21 här, men du kan lika gärna skicka 0,som talar om för funktionen att vi vill använda den defaulta porten för protokollet (21 är FTP protokoll).Därefter skickar vi "UserName och password".Vi loogar in som anonym och "password som Guest ".Nästa skickar vi ett värde som talar om för InternetConnect vilken service vi önskar.Jag använde en namngiven konstant INTERNET_SERVICE_FTP som är samma som 1.
Du kan använda vilken du vill av dessa här nedan.
Private Const INTERNET_SERVICE_FTP = 1
Private Const INTERNET_SERVICE_GOPHER = 2
Private Const INTERNET_SERVICE_HTTP = 3
Men i vårt fall är vi bara intresserade av FTP. Du kan också skicka värde 0 som argument. Då får funktionen själv lista ut vilken service vi är intresserade av. I det fallet måste vi skriva in det kompletta URL i sServerName parametern tex. (FTP://ftp.microsoft.com). Nästa dwFlags parameter till vilken vi kunde ha skickat &H8000000 (INTERNET_FLAG_PASSIVE) om vi önskat oss passiv FTP semantik. I detta exempel skickar vi helt enkelt 0. Sista parametern (dwContext) är ett användare-definierad värde som identifierar applikationen ifall vi vill använda "callbacks". Vi använder inga callbacks i detta exempel så vi skickar 0.
Steg 3
Anropa FTP funktionen ( FtpGetFile funktion) Först så måste vi deklarera funktionen :
Private Declare Function FtpGetFile _
Lib "wininet.dll" Alias "FtpGetFileA" _
( ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
Sen är det bara att anropa den :
If FtpGetFile(hSession, “dirmap.htm”, “c:\dirmap.htm”, _
False, 0, 1, 0) = False Then
MsgBox “Call to FtpGetFile Failed!”
End If
Först skickar vi hSession som vi fick från anropet till InternetConnect. Sedan namnet och som option sökvägen till filen vi vill komma åt,i detta exempel dirmap.htm.Tredje parametern är den lokala sökvägen och namn. fFailIfExists argumentet bestämmer hur funktionen skall reagera om den lokala
filen redan finns.Vi skickar False som betyder "skriv över gamla filen".
Sedan kommer dwFlagsAndAttributes parametern sätter attribut på lokala filen.Vi sätter inga attribut ,skickar 0. Sedan dwFlags parametern bestämmer hur filen kommer att transporteras 1 = ASCII, 2 = Binary. Sista parametern, igen är callbacks ,vi använder inte den 0.
Steg 4
Stänga handlerna (Städa up) Vi stänger dem i omvänd ordning dvs hSession före hINetSession. För stänga handlerna så är det enda vi behöver gör är att skicka dem till InternetCloseHandle funktionen, som deklareras i VB så här .
Private Declare Function InternetCloseHandle Lib _
"wininet.dll" (ByVal hInet As Long) As Integer
Vi startar städningen :
Call InternetCloseHandle(hSession)
Call InternetCloseHandle(hINetSession)
Det var det hela vi har avverkat de fyra stegen och transfererat en fil från Microsoft till vår lokala hårddisk med hjälp av FTP.
Några andra funktioner
Nu när vi vet hur man får tag i en fil,hur gör man för att lägga upp en fil på servern.? Det är lika enkelt som det ovan beskrivet.Vi behöver gå genom samma fyra steg.Skaffa en Internet connection "handle",och en FTP connection handle. Anropa FtpPutFile funktionen och sedan stänga ner våra "handlers".FtpPutFile funktion deklareras så här :
Private Declare Function FtpPutFile _
Lib "wininet.dll" Alias "FtpPutFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, _
ByVal dwFlags As Long,
ByVal dwContext As Long) As Boolean
Först skicka FTP session handle (den som returneras från InternetConnect funktion) sedan namnet och sökväg för den lokala filen. Sedan dwFlags parametern bestämmer hur filen kommer att transporteras 1 = ASCII, 2 = Binary. Sista parametern, igen är callbacks ,vi använder inte den 0.
If FtpPutFile(hSession, “c:\MyFile.txt”, “shared.txt”, 1, 0) = False Then
MsgBox “The call to FtpPutFile failed.”
End If
Det här anropet kan misslyckas om vi inte har tillstånd att transferera till FTP servern
Det fins också en funktion för att ta bort en fil "Delete" :
Private Declare Function FtpDeleteFile _
Lib "wininet.dll" Alias "FtpDeleteFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszFileName As String) As Boolean
Samma teknik som beskrivits innan, du kan få fel om du inte har tillstånd att utföra "Delete"
Så här kan du döpa om en fil :
Private Declare Function FtpRenameFile _
Lib "wininet.dll" Alias "FtpRenameFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszExisting As String, _
ByVal lpszNewName As String) As Boolean
Samma som kommentar i föregående funktion
Jimmy Staff
Tyvärr
Gösta Thorstrand
Fungerar utmärkt för fil nr 1. När fil nr 2 med samma namn skall hämtas finns kopia av filen i cacheminnet och programmet negligerar instruktionen att hämta ny FTP-fil såvida inte IE:s cache städas manuellt och aktuell cookie deletas, då fungerar funktionen. Kan funktionen ges parametervärde som inte lagrar filen i Cache?