如果防火墙在 Word 模板 VBA 中使用 wininet.dll,则无法从 FTP 下载文件

Posted

技术标签:

【中文标题】如果防火墙在 Word 模板 VBA 中使用 wininet.dll,则无法从 FTP 下载文件【英文标题】:Can't download file from FTP if firewall is on using wininet.dll in Word Template VBA 【发布时间】:2016-08-11 05:00:08 【问题描述】:

我创建了 Word 模板加载项 (.dtom)。它使用 FTP 从服务器下载文件。如果我的防火墙关闭,它工作正常。如果防火墙已打开,则不允许下载。在某些情况下,防火墙是使用防病毒设置的。

这是我的代码,如果防火墙关闭,它可以正常工作。

'Add DLL runtime

Private Declare PtrSafe Function InternetGetConnectedState Lib "wininet.dll" _
(ByRef dwflags As Long, ByVal dwReserved As Long) As Long

Private Declare PtrSafe Function InternetOpenA Lib "wininet.dll" ( _
    ByVal sAgent As String, _
    ByVal lAccessType As Long, _
    ByVal sProxyName As String, _
    ByVal sProxyBypass As String, _
    ByVal lFlags As Long) As Long

Private Declare PtrSafe Function InternetConnectA Lib "wininet.dll" ( _
    ByVal hInternetSession As Long, _
    ByVal sServerName As String, _
    ByVal nServerPort As Long, _
    ByVal sUsername As String, _
    ByVal sPassword As String, _
    ByVal lService As Long, _
    ByVal lFlags As Long, _
    ByVal lcontext As Long) As Long

Private Declare PtrSafe Function FtpGetFileA Lib "wininet.dll" ( _
    ByVal hConnect As Long, _
    ByVal lpszRemoteFile As String, _
    ByVal lpszNewFile As String, _
    ByVal fFailIfExists As Long, _
    ByVal dwFlagsAndAttributes As Long, _
    ByVal dwflags As Long, _
    ByVal dwContext As Long) As Long

Private Declare PtrSafe Function InternetCloseHandle Lib "wininet" ( _
    ByVal hInet As Long) As Long

Private Const INTERNET_FLAG_PASSIVE         As Long = &H8000000 


Public Sub downloadFile()   
    If (fileExists = True) Then
        Kill folderLocation
    End If
    strRemoteFile = "/MyFile.xml"
    strLocalFile = folderLocation
    strHost = "XXX.XXX.XXX.XXX"

    lngPort = 21
    strUser = "myuser"
    strPass = "mypassword"
    'usage
    'FtpDownload "/TEST/test.html", "c:\test.html", "ftp.server.com", 21, "user", "password"
    Dim hOpen   As Long
    Dim hConn   As Long

    hOpen = InternetOpenA("FTPGET", 1, vbNullString, vbNullString, 1)
    hConn = InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, INTERNET_FLAG_PASSIVE, 2)

    If FtpGetFileA(hConn, strRemoteFile, strLocalFile, 1, 0, FTP_TRANSFER_TYPE_UNKNOWN Or INTERNET_FLAG_RELOAD, 0) Then
        Debug.Print "done"
    Else
        Debug.Print "fail"
    End If

    InternetCloseHandle hConn
    InternetCloseHandle hOpen
End Sub

如果防火墙已打开,请建议我如何下载。还建议是否有其他方法可以解决防火墙问题。 (例如,在 Mac VBA 中,我们可以使用 MacScript 中的 Curl 命令下载文件,该命令可以从 VBA 执行)

【问题讨论】:

这更多是防火墙问题而不是 VBA。建议您在 PC 防火墙配置中允许 Word 进行出站连接。可能限制为 FTP 端口和特定的 IP 地址。 @PatricK 让我在更大的场景中告诉你。我已将此加载项提供给我的用户。所有人都使用不同类型的防病毒软件。不能帮大家设置杀毒配置。所以我也需要一种跳过防病毒安全的方法。您的解决方案会跳过所有防病毒软件,还是我必须检查个人:(? 我知道Excel可以直接打开http://链接。也许 Word 可以用ftp:// 做类似的事情?很难判断防病毒软件是否会将其视为“电话回家”威胁并静默阻止它们。您可能必须改为通过 Web 服务器/共享云驱动器使 xml 文件可用。 @PatricK 你能给我推荐一下云驱动器吗?你的意思是像 Google Drive 一样吗? 是的,Google Drive、OneDrive、Dropbox,因为它们为防病毒供应商所熟知。 【参考方案1】:

您必须使用被动 FTP 模式:

InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, INTERNET_FLAG_PASSIVE, 2)

InternetConnect 默认为主动模式,当涉及防火墙或 NAT 时,该模式几乎不可用。

请参阅我在Active and Passive FTP connection modes 上的文章,了解为什么需要使用被动模式。

【讨论】:

我的理解是:我需要把hConn = InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, 0, 2)换成你的hConn = InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, INTERNET_FLAG_PASSIVE, 2)。但是INTERNET_FLAG_PASSIVE 的价值是什么。请给我建议。 0x08000000(VBA 中的&H08000000),请参阅msdn.microsoft.com/en-us/library/windows/desktop/aa383661.aspx 我已经采纳了你的建议。它仍然无法正常工作。我在我的问题中编辑了我的代码。如果我遗漏了什么,你能建议我吗? 你能在防火墙开启的情况下使用任何(独立)FTP 客户端下载文件吗? (在同一台机器上) 我可以从另一个我用 C#.net 创建的软件下载文件

以上是关于如果防火墙在 Word 模板 VBA 中使用 wininet.dll,则无法从 FTP 下载文件的主要内容,如果未能解决你的问题,请参考以下文章

VBA操作WORD(〇)自动智能排版格式化公文模板

用excel中的VBA,然后根据excel中单元格中内容,批量替换一个word的模板doc中的字符。字符有很多处。

如何使用 VBA 将页码字段逻辑插入 Word 模板的页脚?

使用VBA将Excel指定单元格数据字符串或者图表对象插入到Word模板指定书签处

如何用EXCEL的VBA控制WORD文档?

如何使用excel vba从行创建多个word文档?