在Windows Server 2012 R2上从VBA调用批处理文件时出现奇怪的FTP行为

Jon*_*igs 5 ftp excel vba batch-file

我有一个基本的.bat文件连接到FTP服务器,保存CSV文件列表,然后从FTP服务器下载所有CSV文件.我正在使用VBA来调用shell以运行.bat文件.在我的工作笔记本电脑(Windows 10)上,一切运行正常,但如果我在Windows Server 2012 R2上运行它,.bat文件会因为FTP服务器发出错误而卡住:

425无法打开数据连接以传输"/*.csv

我正在使用运行FileZilla服务器的PC进行测试,我也可以访问我客户端的FTP服务器(不确定它们在运行什么).

这就是我尝试过的:

在Windows 10和Windows Server 2012 R2上 - 禁用防火墙,64位操作系统,Excel 2010 32位.

在Windows 10笔记本电脑上:

  • 从命令提示符运行批处理文件工作正常
  • 从我的VBA代码正在使用的Windows运行窗口(Winkey + R)运行命令字符串,工作正常
  • 通过任务计划程序将批处理文件作为任务运行,工作正常
  • 运行调用shell以运行.bat文件的VBA子,工作正常

在Windows Server 2012 R2服务器上:

  • 从命令提示符运行批处理文件工作正常
  • 从我的VBA代码正在使用的Windows运行窗口(Winkey + R)运行命令字符串,工作正常
  • 通过任务计划程序将批处理文件作为任务运行,工作正常

问题:

  • 运行调用shell的VBA sub来运行.bat文件,批处理挂起.观察FTP服务器,批处理文件完成登录,然后显示错误425:

(000046)9/21/2015 10:36:11 AM - test(10.32.0.75)> 150打开"/ .csv"
目录列表的数据通道 (000046)9/21/2015 10:36:22 AM -试验(10.32.0.75)> 425无法为"/转移打开数据连接的.csv"
(000046)2015年9月21日上午10点36分26秒-试验(10.32.0.75)>断开.

当我尝试在Server 2012 R2计算机上使用VBA执行批处理文件时,它似乎只是这样做.我不知所措......任何想法?

批处理文件代码:

@echo off
REM Enter the username
echo user test> ftpcmd.dat

REM Enter the password
echo test>> ftpcmd.dat

REM Change the local computers' directory
echo lcd D:/XLRX/FTP/FTP_Tickets>> ftpcmd.dat

REM Get a list of the csv files we're about to copy
echo ls *.csv D:/XLRX/FTP/TESTCopiedCSV.txt>> ftpcmd.dat

REM Download all the csv files to the local directory
echo mget *.csv>> ftpcmd.dat

REM Remove the files we just downloaded from the FTP server

REM Close the connection
echo quit >> ftpcmd.dat

REM use -d for debugging, -i for preventing user interaction questions
ftp  -i -n -s:ftpcmd.dat xxx.xxx.xxx.xxx

REM Clean Up 
del ftpcmd.dat

REM  Close the command window
EXIT
Run Code Online (Sandbox Code Playgroud)

VBA代码:

'Call the batch file to pull down the FTP tickets to the local server
sToday = Format(Now, "yyyymmdd_hhmm")

''-----------------------------------TEST CODE--------------------------------------''
''The following line works from the Windows RUN prompt on the EnerVest server:
    ''cmd /k "cd /d d:\xlrx\FTP && TESTGetFTPTickets.bat" >> D:\XLRX\FTP\FTP_Logs\TEST.log

If sTesting = "NO" Then
    sFTPLogName = sToday & ".log"     'Sets the FTP log filename
    sCMD = "cmd /k " & """cd /d D:\xlrx\FTP && GetFTPTickets.bat"""
    Else
    sFTPLogName = "TEST_" & sToday & ".log"   'Sets the FTP log filename if testing
    sCMD = "cmd /k " & """cd /d D:\xlrx\FTP && TESTGetFTPTickets.bat"""
End If

sLog = ">> " & sFTPLogFolder & "\" & sFTPLogName
vArguments = Array(sCMD, sLog)     'New Code 9/20/2015

sShell = Join(vArguments, " ")                  'Joins the above arguments into a string separated by " " (spaces)


'Call the Shell (command line) and use the sShell
Call Shell(sShell)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ryl 1

建立从服务器到客户端的主动模式连接显然存在问题。我不知道为什么它不起作用(阻止 Excel 及其子进程打开侦听端口的本地策略?)。但它能在 Windows 10 上运行实际上几乎是一个奇迹。

请参阅我关于FTP 连接模式的文章,了解为什么由于无处不在的防火墙/NAT/代理,主动模式现在很难工作。


您最好使用被动模式。但Windowsftp.exe不支持。

使用任何其他命令行 FTP 客户端。所有其他都支持被动模式。

例如,使用WinSCP 脚本的等效批处理文件:

@echo off
winscp.com /log=c:\path\log.log /command ^
    "open ftp://user:test@xxx.xxx.xxx.xxx" ^
    "lcd D:\XLRX\FTP\FTP_Tickets" ^
    "get *.csv" ^
    "exit"
Run Code Online (Sandbox Code Playgroud)

WinSCP 默认为被动模式。

请参阅将 Windowsftp.exe脚本转换为 WinSCP 的指南。

(我是WinSCP的作者)