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

不使用商业第三方FTP组件,VBScript上传文件至FTP服务器的问题

解决VBScript Shell.Application FTP上传的CopyHere问题

我来帮你排查这个FTP上传的问题——用Shell.Application的CopyHere方法做FTP传输确实容易踩一些隐性的坑,尤其是参数配置和连接逻辑上的问题。你怀疑objFTP.CopyHere objItem, copyType有问题是对的,咱们一步步拆解:

1. 先修正CopyHere的参数组合

你用的copyType = 16只设置了FOF_NOCONFIRMATION(不显示确认对话框),但脚本运行时通常需要更“安静”的模式,避免弹窗或错误提示中断流程。建议换成更合适的参数组合:

Const FOF_SILENT = 4           ' 不显示进度对话框
Const FOF_NOCONFIRMATION = 16  ' 不显示确认对话框
Const FOF_NOERRORUI = 1024     ' 不显示错误提示
Const copyType = FOF_SILENT + FOF_NOCONFIRMATION + FOF_NOERRORUI

这些参数组合能让上传过程在后台静默执行,避免因为交互弹窗导致脚本卡住。

2. 修复FTP连接的逻辑问题

直接在URL里拼接用户名密码的方式,部分FTP服务器可能不支持(比如包含特殊字符的密码),而且如果连接失败,objFTP会变成Nothing,后续调用CopyHere直接报错。建议改成先连接FTP服务器,再登录并切换目录:

' 先连接FTP服务器根目录
strFTP = "ftp://" & FTPHost
Set objFTP = oShell.NameSpace(strFTP)
If objFTP Is Nothing Then
    Wscript.Echo "无法连接到FTP服务器: " & FTPHost
    Exit Sub
End If

' 执行登录
objFTP.Items().Parent.Logon FTPUser, FTPPass

' 切换到目标目录
Set objFTP = objFTP.Folders.Item(FTPDir)
If objFTP Is Nothing Then
    Wscript.Echo "FTP目标目录不存在: " & FTPDir
    Exit Sub
End If

这种方式比直接拼接URL更可靠,还能提前排查连接和目录存在的问题。

3. 优化错误处理和等待逻辑

你注释掉了On Error Resume Next,但脚本运行时需要捕获错误;另外固定80秒等待太死板,建议改成循环检查上传状态(比如对比本地文件和FTP文件的存在性),或者至少在关键步骤后检查错误:

On Error Resume Next
' ... 连接和登录代码 ...
If Err.Number <> 0 Then
    Wscript.Echo "登录失败: " & Err.Description
    Err.Clear
    Exit Sub
End If

' ... 上传代码 ...
objFTP.CopyHere objItem, copyType
If Err.Number <> 0 Then
    Wscript.Echo "上传失败: " & Err.Description
    Err.Clear
    Exit Sub
End If

' 替代固定等待:循环检查FTP上的文件是否存在(简单版)
Dim checkCount
checkCount = 0
Do While checkCount < 20  ' 最多等20秒,每次等1秒
    Wscript.Sleep 1000
    On Error Resume Next
    Set remoteFile = objFTP.ParseName(objItem.Name)
    If Not remoteFile Is Nothing Then
        Exit Do
    End If
    checkCount = checkCount + 1
Loop
If checkCount >= 20 Then
    Wscript.Echo "上传超时,可能未完成"
End If

修改后的完整代码

整合以上所有优化点后的代码:

Set oShell = CreateObject("Shell.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
path = "D:\test\"
FTPUpload(path)

Sub FTPUpload(path)
    On Error Resume Next
    ' 定义CopyHere的静默参数
    Const FOF_SILENT = 4
    Const FOF_NOCONFIRMATION = 16
    Const FOF_NOERRORUI = 1024
    Const copyType = FOF_SILENT + FOF_NOCONFIRMATION + FOF_NOERRORUI

    FTPUser = "xxxxx"
    FTPPass = "xxxxxx"
    FTPHost = "xxxx.xxx"
    FTPDir = "/public_html/testfolder/"

    ' 1. 连接FTP服务器根目录
    strFTP = "ftp://" & FTPHost
    Set objFTP = oShell.NameSpace(strFTP)
    If objFTP Is Nothing Then
        Wscript.Echo "无法连接到FTP服务器: " & FTPHost
        Exit Sub
    End If

    ' 2. 登录FTP
    objFTP.Items().Parent.Logon FTPUser, FTPPass
    If Err.Number <> 0 Then
        Wscript.Echo "FTP登录失败: " & Err.Description
        Err.Clear
        Exit Sub
    End If

    ' 3. 切换到目标上传目录
    Set objFTP = objFTP.Folders.Item(FTPDir)
    If objFTP Is Nothing Then
        Wscript.Echo "FTP目标目录不存在: " & FTPDir
        Exit Sub
    End If

    ' 4. 准备要上传的文件
    ufile = path & "bappy.txt"
    If objFSO.FileExists(ufile) Then
        Set objFile = objFSO.getFile(ufile)
        strParent = objFile.ParentFolder
        Set objFolder = oShell.NameSpace(strParent)
        Set objItem = objFolder.ParseName(objFile.Name)
        
        If objItem Is Nothing Then
            Wscript.Echo "无法获取本地文件: " & ufile
            Exit Sub
        End If

        Wscript.Echo "正在上传文件 " & objItem.Name & " 到 " & strFTP & FTPDir
        objFTP.CopyHere objItem, copyType

        If Err.Number <> 0 Then
            Wscript.Echo "上传失败: " & Err.Description
            Err.Clear
            Exit Sub
        End If

        ' 5. 等待上传完成(循环检查)
        Dim checkCount
        checkCount = 0
        Do While checkCount < 20
            Wscript.Sleep 1000
            Set remoteFile = objFTP.ParseName(objItem.Name)
            If Not remoteFile Is Nothing Then
                Wscript.Echo "上传完成!"
                Exit Do
            End If
            checkCount = checkCount + 1
        Loop
        If checkCount >= 20 Then
            Wscript.Echo "上传超时,请检查服务器状态"
        End If
    Else
        Wscript.Echo "本地文件不存在: " & ufile
    End If
End Sub

额外注意事项

  • 确保脚本运行的用户有足够的权限访问本地文件和FTP服务器
  • 如果FTP服务器要求被动模式,Shell.Application默认会使用被动模式,但部分老服务器可能需要主动模式,这时候Shell.Application可能无法支持,只能改用Windows自带的ftp.exe命令行工具(可以用VBScript调用WshShell.Run执行批处理)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:45:26