Jag håller på att bygga en ftpclient class i dotnet, allt funkar förutom att få tillbaka error och response. Vad är det som inte fungerar då? Jag har testat den som stringbuilder också. Ok, ett skott till: skall inte lpszBuffer vara ByRef? lpszbuffer ska inte vara byref, då kraschar det rejält :-) (har testat) Här kommer all koden jag har.... jag fortsätter med höftskott: och om du kör <MarshalAs(UnmanagedType.LPTStr)> för din StringBuilder? Tackar Johan :-)InternetGetLastResponseInfo (Win32 api)
Är det någon som har en lösning på nedanstående som inte fungerar ?
'Kodutdrag
<code>
Private Declare Auto Function InternetGetLastResponseInfo Lib "wininet.dll" Alias "InternetGetLastResponseInfoA" (ByVal lpdwError As Int32, ByVal lpszBuffer As String, ByVal lpdwBufferLength As Int32) As Boolean
<VBFixedString(MAX_PATH), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Public strErrInfo As String
Public Function GetLastInternetResponse()
Dim lErr As Int32
strErrInfo = New String(Chr(0), 2048)
'retrieve the last respons info
InternetGetLastResponseInfo(lErr, strErrInfo, 2048)
'show the last response info
Return strErrInfo.ToString
End Function
</code>Sv: InternetGetLastResponseInfo (Win32 api)
enligt http://www.dotnet247.com/247reference/msgs/40/203857.aspx
ska väl din lpszBuffer vara deklarerad som en StringBuilder och inte en string...Sv: InternetGetLastResponseInfo (Win32 api)
Problemet är att funktionen returnerar tomsträng hela tiden.
Jag testar genom att simulera en error genom att ange en användare som inte finns när jag loggar på ftpservern.Sv: InternetGetLastResponseInfo (Win32 api)
Annars kan du väl använda
http://www.csharphelp.com/archives/archive9.html skriven i C# men du kan ju kompilera det och använda från vb.net ändå...Sv: InternetGetLastResponseInfo (Win32 api)
Alltså, så gott som allt annat man kan tänkas behöva i en ftpclient funkar i min ftpclass, förutom detta.
Så att ta något annat känns lite tråkigt, men tack för tipset :-)Sv: InternetGetLastResponseInfo (Win32 api)
<code>
Imports System.Runtime.InteropServices
Public Class FTP
Private Const FTP_TRANSFER_TYPE_UNKNOWN = &H0
Private Const FTP_TRANSFER_TYPE_BINARY = &H2
Private Const FTP_TRANSFER_TYPE_ASCII = &H1
Private Const INTERNET_OPEN_TYPE_DIRECT = 1
Private Const INTERNET_SERVICE_FTP = 1
Private Const INTERNET_FLAG_PASSIVE = &H8000000
Private Const FILE_ATTRIBUTE_READONLY = &H1
Private Const FILE_ATTRIBUTE_HIDDEN = &H2
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
Private Const FILE_ATTRIBUTE_COMPRESSED = &H800
Private Const FILE_ATTRIBUTE_OFFLINE = &H1000
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Int32, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Int32) As Int32
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Int32, ByVal sServerName As String, ByVal nServerPort As Integer, ByVal sUserName As String, ByVal sPassword As String, ByVal lService As Int32, ByVal lFlags As Int32, ByVal lContext As Int32) As Int32
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Int32) As Int32
Private Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias "FtpSetCurrentDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszDirectory As String) As Boolean
Private Declare Function FtpGetCurrentDirectory Lib "wininet.dll" Alias "FtpGetCurrentDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszCurrentDirectory As String, ByVal lpdwCurrentDirectory As Int32) As Int32
Private Declare Function FtpCreateDirectory Lib "wininet.dll" Alias "FtpCreateDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszDirectory As String) As Boolean
Private Declare Function FtpRemoveDirectory Lib "wininet.dll" Alias "FtpRemoveDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszDirectory As String) As Boolean
Private Declare Function FtpDeleteFile Lib "wininet.dll" Alias "FtpDeleteFileA" (ByVal hFtpSession As Int32, ByVal lpszFileName As String) As Boolean
Private Declare Function FtpRenameFile Lib "wininet.dll" Alias "FtpRenameFileA" (ByVal hFtpSession As Int32, ByVal lpszExisting As String, ByVal lpszNew As String) As Boolean
Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" (ByVal hFtpSession As Int32, ByVal lpszLocalFile As String, ByVal lpszRemoteFile As String, ByVal dwFlags As Int32, ByVal dwContext As Int32) As Boolean
Private Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" (ByVal hConnect As Int32, ByVal lpszRemoteFile As String, ByVal lpszNewFile As String, ByVal fFailIfExists As Int32, ByVal dwFlagsAndAttributes As Int32, ByVal dwFlags As Int32, ByRef dwContext As Int32) As Boolean
Private Declare Auto Function InternetGetLastResponseInfo Lib "wininet.dll" Alias "InternetGetLastResponseInfoA" (ByRef lpdwError As Int32, ByVal lpszBuffer As System.Text.StringBuilder, ByRef lpdwBufferLength As Int32) As Boolean
Private Declare Auto Function FtpFindFirstFile Lib "wininet.dll" Alias "FtpFindFirstFileA" (ByVal hFtpSession As Int32, ByVal lpszSearchFile As String, ByRef lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Int32, ByVal dwContent As Int32) As Int32
Private Declare Auto Function InternetFindNextFile Lib "wininet.dll" Alias "InternetFindNextFileA" (ByVal hFind As Int32, ByRef lpvFindData As WIN32_FIND_DATA) As Int32
Private lngInternetSession As Int32
Private lngFTPSession As Int32
Public Enum FileTransferType
ftpUnknown = FTP_TRANSFER_TYPE_UNKNOWN
ftpAscii = FTP_TRANSFER_TYPE_ASCII
ftpBinary = FTP_TRANSFER_TYPE_BINARY
End Enum
Public Enum ConnectionModes
Active = 0
Passive = INTERNET_FLAG_PASSIVE
End Enum
Const MAX_PATH = 260
Private Structure FILETIME
Private dwLowDateTime As Int32
Private dwHighDateTime As Int32
End Structure
Private Structure WIN32_FIND_DATA
Dim dwFileAttributes As Integer
Dim ftCreationTime As FILETIME
Dim ftLastAccessTime As FILETIME
Dim ftLastWriteTime As FILETIME
Dim nFileSizeHigh As Integer
Dim nFileSizeLow As Integer
Dim dwReserved0 As Integer
Dim dwReserved1 As Integer
<VBFixedString(MAX_PATH), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Public cFileName As String
<VBFixedString(14), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=14)> Public cAlternate As String
End Structure
'Skapa en kontakt med servern, returnerar True ifall det gick bra
Public Function ConnectToServer(ByVal Server As String, Optional ByVal Port As Int32 = 21, Optional ByVal ConnectionMode As ConnectionModes = ConnectionModes.Active, Optional ByVal Username As String = "", Optional ByVal Password As String = "") As Boolean
Dim blnRet As Boolean
Try
'Stäng connection för säkerhets skull
CloseConnection()
If Username = "" Then Username = "Anonymous@Anonymous.com"
lngInternetSession = InternetOpen("FTPPUT", INTERNET_OPEN_TYPE_DIRECT, vbNullString, vbNullString, 0)
If lngInternetSession <> 0 Then lngFTPSession = InternetConnect(lngInternetSession, Server, Port, Username, Password, INTERNET_SERVICE_FTP, ConnectionMode, 0)
If lngFTPSession <> 0 Then blnRet = True
ConnectToServer = blnRet
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
'Stäng kontakten till servern
Public Sub CloseConnection()
If lngFTPSession <> 0 Then InternetCloseHandle(lngFTPSession)
If lngInternetSession <> 0 Then InternetCloseHandle(lngInternetSession)
End Sub
'Skicka upp en fil på servern med valfri transfertype, Ifall annan katalog än din hemmakatalog specifiera den
Public Function PutFile(ByVal LocalFilePath As String, ByVal RemoteFilename As String, Optional ByVal TransferType As FileTransferType = FileTransferType.ftpBinary) As Boolean
Try
Return FtpPutFile(lngFTPSession, LocalFilePath, RemoteFilename, TransferType, 0)
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
'Hämta en fil från servern med valfri transfertype, Ifall annan katalog än din hemmakatalog specifiera den
Public Function GetFile(ByVal LocalFilePath As String, ByVal RemoteFilename As String, Optional ByVal TransferType As FileTransferType = FileTransferType.ftpBinary) As Boolean
Try
If Right(LocalFilePath, 1) <> "\" Then LocalFilePath = LocalFilePath & "\"
Return FtpGetFile(lngFTPSession, RemoteFilename, LocalFilePath & RemoteFilename, False, 0, TransferType, 0)
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function DeleteFile(ByVal strFile As String) As Boolean
Try
Return FtpDeleteFile(lngFTPSession, strFile)
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function RenameFile(ByVal oldFileName As String, ByVal NewFileName As String) As Boolean
Try
Return FtpRenameFile(lngFTPSession, oldFileName, NewFileName)
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function CreateDirectory(ByVal DirectoryName As String) As Boolean
Try
Return FtpCreateDirectory(lngFTPSession, DirectoryName & Chr(0))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function RemoveDirectory(ByVal DirectoryName As String) As Boolean
Try
Return FtpRemoveDirectory(lngFTPSession, DirectoryName)
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
'Hämta filer från servern
Public Function GetFileList() As Object
Dim pData As WIN32_FIND_DATA, hFind As Long, lRet As Long
Dim ReturnFile() As String, cnt As Long
Dim Filename As String, blnFind As Boolean
Try
pData.cAlternate = ""
pData.cFileName = ""
pData.cAlternate = New String(Chr(0), 14)
'Skapa buffer
pData.cFileName = New String(Chr(0), MAX_PATH)
'Hitta första filen
hFind = FtpFindFirstFile(lngFTPSession, "*.*", pData, 0, 0)
'Ifall ingen fil finns gå ur
If hFind = 0 Then Exit Function
If pData.dwFileAttributes <> FILE_ATTRIBUTE_DIRECTORY Then
'Kolla första filen och ifall giltig lägg in den i arrayen som ska returneras
Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
If Filename <> "System Volume Information" And Filename <> "RECYCLER" Then
ReDim Preserve ReturnFile(cnt)
ReturnFile(cnt) = Filename
blnFind = True
cnt += 1
End If
End If
Do
'Skapa buffer
pData.cFileName = New String(Chr(0), MAX_PATH)
'Hitta första filen
lRet = InternetFindNextFile(hFind, pData)
'Ifall ingen fil finns gå ur
If lRet = 0 Then Exit Do
If pData.dwFileAttributes <> FILE_ATTRIBUTE_DIRECTORY Then
'Ifall filen är giltig lägg in den i arrayen som ska returneras
Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
ReDim Preserve ReturnFile(cnt)
ReturnFile(cnt) = Filename
blnFind = True
cnt = cnt + 1
End If
Loop
'stäng ner
InternetCloseHandle(hFind)
If blnFind Then GetFileList = ReturnFile
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function GetDirectoryList() As Object
Dim pData As WIN32_FIND_DATA, hFind As Long, lRet As Long
Dim ReturnFile() As String, cnt As Long
Dim Filename As String
Try
ReDim Preserve ReturnFile(cnt)
ReturnFile(cnt) = ".."
cnt += 1
pData.cAlternate = ""
pData.cFileName = ""
pData.cAlternate = New String(Chr(0), 14)
'Skapa buffer
pData.cFileName = New String(Chr(0), MAX_PATH)
'Hitta första filen
hFind = FtpFindFirstFile(lngFTPSession, "*.*", pData, 0, 0)
'Ifall ingen fil finns gå ur
If hFind = 0 Then
Return ReturnFile
Exit Function
End If
If pData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY Then
'Kolla första filen och ifall giltig lägg in den i arrayen som ska returneras
Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
If Filename <> "System Volume Information" And Filename <> "RECYCLER" And Filename <> ".." Then
ReDim Preserve ReturnFile(cnt)
ReturnFile(cnt) = Filename
cnt += 1
End If
End If
Do
'Skapa buffer
pData.cFileName = New String(Chr(0), MAX_PATH)
'Hitta första filen
lRet = InternetFindNextFile(hFind, pData)
'Ifall ingen fil finns gå ur
If lRet = 0 Then Exit Do
If pData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY Then
'Ifall filen är giltig lägg in den i arrayen som ska returneras
Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
If Filename <> "System Volume Information" And Filename <> "RECYCLER" And Filename <> ".." Then
ReDim Preserve ReturnFile(cnt)
ReturnFile(cnt) = Filename
cnt = cnt + 1
End If
End If
Loop
'stäng ner
InternetCloseHandle(hFind)
Return ReturnFile
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function SetWorkingDir(ByVal WorkingDir As String) As Boolean
Try
Return FtpSetCurrentDirectory(lngFTPSession, WorkingDir)
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function GetLastInternetResponse()
Dim lErr As Int32, s As New System.Text.StringBuilder()
Dim l As Int32
Try
InternetGetLastResponseInfo(lErr, s, l)
s.Capacity = l + 1
InternetGetLastResponseInfo(lErr, s, s.Length)
'show the last response info
Return s.ToString
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Protected Overrides Sub Finalize()
CloseConnection()
MyBase.Finalize()
End Sub
End Class
</code>Sv: InternetGetLastResponseInfo (Win32 api)
Sv: InternetGetLastResponseInfo (Win32 api)
Det funkar nu om jag tar bort Auto ur api deklarationen.