【问题标题】:FTP:Upload file to FTP and verifyFTP:上传文件到FTP并验证
【发布时间】:2012-10-22 10:56:24
【问题描述】:

我正在使用VBS来

  1. 上传文件到 FTP
  2. 验证上传过程

我使用的方法是创建一个文本文件,用适当的命令填充它,然后在 windows 中使用 ftp.exe 执行它。

            FTPCommand = "%systemroot%\System32\ftp.exe -s:session.txt"
            FTPCommand = objshell.ExpandEnvironmentStrings(FTPCommand)
            objshell.Run FTPCommand,, vbTrue
            fso.DeleteFile "session.txt", vbTrue

第 1 部分使用以下代码完成:

            Set SessionFile = fso.OpenTextFile("session.txt", 2, vbTrue)
            With SessionFile
                .WriteLine "open  abcd.com"
                .WriteLine "username"
                .WriteLine "pwd"
                .WriteLine "cd /Test/Test1"
                .WriteLine "put """ & File.Path & """"
                .WriteLine "quit"
                .Close
            End With

            FTPCommand = "%systemroot%\System32\ftp.exe -s:session.txt"
            FTPCommand = objshell.ExpandEnvironmentStrings(FTPCommand)
            objshell.Run FTPCommand,, vbTrue
            fso.DeleteFile "session.txt", vbTrue

第 2 部分是使用以下代码完成的:

            Set SessionFile = fso.OpenTextFile("session.txt", 2, vbTrue)
            With SessionFile
                .WriteLine "open  abcd.com"
                .WriteLine "username"
                .WriteLine "pwd"
                .WriteLine "cd /Test/Test1"
                .WriteLine "ls"
                .WriteLine "close"
                .WriteLine "bye"
                .Close
            End With
            FTPCommand = "%systemroot%\System32\ftp.exe -s:session.txt"
            FTPCommand = objshell.ExpandEnvironmentStrings(FTPCommand)

            set ObjExec=objshell.exec(FTPCommand)
            DO WHILE ObjExec.status=0 : wscript.sleep 50 : LOOP
            StrTemp=ObjExec.stdout.readall

            IF instr(1,StrTemp,File.Name,1)<>0 THEN
                AlertMessage = AlertMessage & vbTab & "STATUS: UPLOAD SUCCESSFUL" & vbCrLf & vbCrLf
            ELSE
                AlertMessage = AlertMessage & vbTab & "STATUS: UPLOAD FAILED" & vbCrLf & vbCrLf
            END IF
            fso.DeleteFile "session.txt", vbTrue 

问题在于(在第 2 部分代码中)

之后的代码
            DO WHILE ObjExec.status=0 : wscript.sleep 50 : LOOP

永远不会返回。因此文件已上传,但检查状态的代码永远不会返回。
session.txt 文件没有被删除,当我执行命令时

%systemroot%\System32\ftp.exe -s:session.txt

手动它确实向我显示了文件列表(因为 ls 命令)。

我有 3 个问题:

  1. 为什么它不返回。从哪里开始调试?
  2. 无论如何我可以上传文件并检查其状态(也许通过 “put”命令后ftp命令返回的错误码)。
  3. 是否在代码中指定了错误的目录来上传 文件,cd 命令失败,它错误地将文件“放入” 根文件夹。检查文件上传的代码也是如此。所以 即使指定的目录错误,程序也会将其返回为 成功

编辑 1: 我试过用

.WriteLine "cd /Test"

它奏效了。是目录切换(两个文件夹深)导致问题吗?

编辑 2: 我手动运行了 ls 命令,它运行良好。输出为:

226 Transfer complete.
ftp: 586493 bytes received in 4.28Seconds 137.00Kbytes/sec.

586493 字节是否太多了?

我认为问题可能是:
1)LS命令返回的文件数量很大。
2)我正在访问的目录结构。

编辑:3 从这个microsoft 网站看来,上述第 1 点是罪魁祸首:

控制台应用程序的 StdOut 和 StdErr 流共享相同的 内部 4KB 缓冲区。此外,仅 WshScriptExec 对象 提供对这些流的同步读取操作。同步 读取操作在调用脚本之间引入了依赖关系 从这些流中读取,子进程写入这些流 流,这可能导致死锁情况。

【问题讨论】:

  • 手动调用FTP.EXE 并输入命令可能会更容易调试。从ftp ftp.site.com 开始,它会询问您的用户名和密码,然后您只需从那里按照脚本进行操作即可。
  • 我知道验证文件是否正确上传的唯一方法是下载它,并将其与原始文件进行比较。为确保正确传输,您可以设置 ASCII 或 BINARY 开关,具体取决于它是文本文件还是二进制文件。这样做很容易,您只需在传输文件之前发送文本asciibinary。不这样做可能会导致意外问题,因为ftp 处理传输的方式不同。
  • 就像我说的,如果我手动运行命令,它运行得非常好(在 4.28 秒内收到 586493 个字节)。问题是 VBS 以某种方式不返回结果。我不知道从哪里开始调试。
  • 执行是否超过了DO WHILE ObjExec.status=0 : wscript.sleep 50 : LOOP 行?
  • 否,行 DO WHILE ObjExec.status=0 : wscript.sleep 50 : LOOP 永远不会完成执行。我猜 ObjExec.status 永远不会变为零。

标签: windows batch-file vbscript ftp


【解决方案1】:

我认为问题在于您从流程中读取标准输出的方式。我成功地使用了这种技术如下,对不起,我没有时间调整你的脚本并尝试一下,所以这取决于你。

下面执行一个ping来检查服务器是否在线。

Function IsOnline(Address) 
  Dim strText 
  IsOnline = False 
  Set oExecObj = oShell.Exec("%comspec% /c ping -a -n 1 -w 20 " & Address) 
  Do While Not oExecObj.StdOut.AtEndOfStream 
    strText = oExecObj.StdOut.ReadAll() 
    If Instr(strText, "Reply from") > 0 Then 
      IsOnline = True 
      Exit Function 
    End If 
  Loop 
End Function       

【讨论】:

  • 即使收到“Reply from”也不表示主机已启动:有时您会收到来自路由器的回复,通知您远程网络无法访问
  • 嗨 ftiela,这不是重点,如果你想知道 pc 是否在线,有更好的解决方案,我只是用它来展示 stdout 的使用并避免使用其他 cmets,不,这不是使用它的方式,但它可靠且有效
  • 是的,我知道这不是重点,但在某些情况下,检查您是否收到“回复”并不意味着主机已启动:回复可能来自路由器或您的主机(例如http://serverfault.com/questions/131136/ping-replies-from-same-computer-with-destination-host-unreachable-no-route。我认为最好检查回复的状态,而不仅仅是“回复”字符串。
  • 如果有人会使用这种技术,你可能是对的,我面临的大多数时候我需要检查电脑是否启动的问题是我需要在几分钟内检查数百台电脑。尚未找到解决该问题的方法
猜你喜欢
  • 2012-03-12
  • 2012-07-06
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 2013-06-30
相关资源
最近更新 更多