You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

更换FTP服务器后VB6代码无法上传文件求助(FtpOpenFile返回0)

VB6 FTP Upload Fails on New Server (FtpOpenFile Returns 0)

Let's break down your issue and walk through the most likely fixes based on your code and the working ExtraFTP log.

First, the key observation: your code creates an empty file on the new server but can't get a valid handle via FtpOpenFile—this suggests the initial file creation works, but the data connection or write permissions are failing. Let's compare your code to the successful ExtraFTP session and fix the gaps.

Step 1: Capture the Exact Error Code

First, let's get specific details on why FtpOpenFile is returning 0. Add the GetLastError declaration and capture the error when it fails—this will give us concrete clues:

Private Declare Function GetLastError Lib "kernel32" () As Long

' Inside your UploadFile function, after checking hFile = 0:
If hFile = 0 Then
    Dim errCode As Long
    errCode = GetLastError()
    MsgBox "FtpOpenFile failed. Error code: " & errCode & vbCrLf & _
           "Check WinINet error codes for details."
    Exit Function
End If

Common error codes here might point to connection issues (like 12031 = connection reset) or mode mismatches.

Step 2: Enable Passive FTP Mode

Looking at your ExtraFTP log, it explicitly uses PASV mode, but WinINet's default is active (PORT) mode. Many modern FTP servers block active mode due to firewall restrictions. Let's enable passive mode for your connection:

First, add the InternetSetOption declaration:

Private Declare Function InternetSetOption Lib "wininet.dll" Alias "InternetSetOptionA" ( _
    ByVal hInternet As Long, _
    ByVal dwOption As Long, _
    lpBuffer As Any, _
    ByVal dwBufferLength As Long _
) As Long
Const INTERNET_OPTION_USE_PASSIVE_FTP = &H20000

Then, right after calling InternetConnect, enable passive mode:

hConnection = InternetConnect(hInternet, sServerName, INTERNET_INVALID_PORT_NUMBER, _
    sUserName, sPassword, INTERNET_SERVICE_FTP, 0, 0)

' Enable passive FTP
Dim enablePassive As Long
enablePassive = 1 ' 1 = enable, 0 = disable
If InternetSetOption(hConnection, INTERNET_OPTION_USE_PASSIVE_FTP, enablePassive, 4) = 0 Then
    MsgBox "Failed to set passive mode."
    Exit Function
End If

Step 3: Match Working Directory & UTF8 Settings

Your ExtraFTP log does two critical things your code doesn't:

  1. Switches to the correct working directory (CWD /michlol/HomeMI)
  2. Enables UTF8 encoding (OPTS UTF8 ON)

Let's add both to your code:

Add Directory Change

First, declare FtpSetCurrentDirectory:

Private Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias "FtpSetCurrentDirectoryA" ( _
    ByVal hFtpSession As Long, _
    ByVal lpszDirectory As String _
) As Boolean

Then, after enabling passive mode, switch to the target directory:

If Not FtpSetCurrentDirectory(hConnection, "/michlol/HomeMI") Then
    MsgBox "Failed to switch to target directory."
    Exit Function
End If

Enable UTF8 Encoding

Some servers require UTF8 for filename handling (even if your filenames are ASCII). Add the FtpCommand declaration to send the OPTS UTF8 ON command:

Private Declare Function FtpCommand Lib "wininet.dll" Alias "FtpCommandA" ( _
    ByVal hFtpSession As Long, _
    ByVal fExpectResponse As Boolean, _
    ByVal dwFlags As Long, _
    ByVal lpszCommand As String, _
    dwContext As Long, _
    phFtpCommand As Long _
) As Boolean
Const FTP_TRANSFER_TYPE_ASCII = &H1

Send the command after logging in:

' Send OPTS UTF8 ON to match ExtraFTP's behavior
If Not FtpCommand(hConnection, True, FTP_TRANSFER_TYPE_ASCII, "OPTS UTF8 ON", 0, 0) Then
    MsgBox "Warning: Failed to set UTF8 mode (server may not require this, but try anyway)."
End If

Step 4: Double-Check FtpOpenFile Parameters

Your current FtpOpenFile call uses &H40000000 (which is GENERIC_WRITE)—that's correct, but ensure RemoteFile is just the filename (like Be072222.mdb) now that we've switched directories, not a full path. Also, trim any hidden spaces from the filename:

RemoteFile = Trim(RemoteFile)
hFile = FtpOpenFile(hConnection, RemoteFile, &H40000000, FTP_TRANSFER_TYPE_BINARY, 0)

Full Modified Code Snippet

Putting it all together, your UploadFile function would look like this:

Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags 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 lService As Long, ByVal lFlags As Long, ByVal lContext As Long) As Long
Private Declare Function FtpOpenFile Lib "wininet.dll" Alias "FtpOpenFileA" (ByVal hFtpSession As Long, ByVal sBuff As String, ByVal Access As Long, ByVal flags As Long, ByVal Context As Long) As Long
Private Declare Function InternetSetOption Lib "wininet.dll" Alias "InternetSetOptionA" (ByVal hInternet As Long, ByVal dwOption As Long, lpBuffer As Any, ByVal dwBufferLength As Long) As Long
Private Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias "FtpSetCurrentDirectoryA" (ByVal hFtpSession As Long, ByVal lpszDirectory As String) As Boolean
Private Declare Function FtpCommand Lib "wininet.dll" Alias "FtpCommandA" (ByVal hFtpSession As Long, ByVal fExpectResponse As Boolean, ByVal dwFlags As Long, ByVal lpszCommand As String, dwContext As Long, phFtpCommand As Long) As Boolean
Private Declare Function GetLastError Lib "kernel32" () As Long
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInternet As Long) As Long

Const INTERNET_OPEN_TYPE_PRECONFIG = 0
Const INTERNET_INVALID_PORT_NUMBER = 0
Const INTERNET_SERVICE_FTP = 1
Public Const FTP_TRANSFER_TYPE_BINARY = &H2
Const INTERNET_OPTION_USE_PASSIVE_FTP = &H20000
Const FTP_TRANSFER_TYPE_ASCII = &H1
Const scUserAgent As String = "VB6 FTP Client"

Public Function UploadFile(sServerName As String, sUserName As String, sPassword As String, RemoteFile As String) As Boolean
    Dim hInternet As Long
    Dim hConnection As Long
    Dim hFile As Long
    Dim errCode As Long
    
    hInternet = InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0)
    If hInternet = 0 Then
        MsgBox "InternetOpen failed. Error: " & GetLastError()
        UploadFile = False
        Exit Function
    End If
    
    hConnection = InternetConnect(hInternet, sServerName, INTERNET_INVALID_PORT_NUMBER, sUserName, sPassword, INTERNET_SERVICE_FTP, 0, 0)
    If hConnection = 0 Then
        errCode = GetLastError()
        MsgBox "InternetConnect failed. Error: " & errCode
        InternetCloseHandle hInternet
        UploadFile = False
        Exit Function
    End If
    
    ' Enable passive FTP mode
    Dim enablePassive As Long
    enablePassive = 1
    If InternetSetOption(hConnection, INTERNET_OPTION_USE_PASSIVE_FTP, enablePassive, 4) = 0 Then
        MsgBox "Warning: Failed to enable passive mode (may cause issues)."
    End If
    
    ' Set UTF8 mode (matches ExtraFTP)
    If Not FtpCommand(hConnection, True, FTP_TRANSFER_TYPE_ASCII, "OPTS UTF8 ON", 0, 0) Then
        MsgBox "Warning: Failed to set UTF8 mode (server may not require this)."
    End If
    
    ' Switch to target directory
    If Not FtpSetCurrentDirectory(hConnection, "/michlol/HomeMI") Then
        errCode = GetLastError()
        MsgBox "Failed to change directory. Error: " & errCode
        InternetCloseHandle hConnection
        InternetCloseHandle hInternet
        UploadFile = False
        Exit Function
    End If
    
    ' Trim remote filename to avoid hidden spaces
    RemoteFile = Trim(RemoteFile)
    hFile = FtpOpenFile(hConnection, RemoteFile, &H40000000, FTP_TRANSFER_TYPE_BINARY, 0)
    If hFile = 0 Then
        errCode = GetLastError()
        MsgBox "Unable to create the remote file. Error code: " & errCode
        InternetCloseHandle hConnection
        InternetCloseHandle hInternet
        UploadFile = False
        Exit Function
    End If
    
    ' Add your file writing logic here (using InternetWriteFile)
    
    ' Cleanup
    InternetCloseHandle hFile
    InternetCloseHandle hConnection
    InternetCloseHandle hInternet
    
    UploadFile = True
End Function

Key Notes

  • Passive mode is the most likely fix here—most modern servers block active mode due to firewall rules.
  • Matching the working directory ensures your file is written to the correct location.
  • UTF8 encoding is a safeguard, even for ASCII filenames, since some servers enforce it.

If these steps don't resolve the issue, share the error code you get—this will help narrow down the remaining problems.

内容的提问来源于stack exchange,提问作者yoram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:32:33