2012-10-22 163 views
1

我使用VBS到FTP:上传文件到FTP和验证

  1. 将文件上传到FTP
  2. 确认上传过程

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

  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部分使用此代码完成:

  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 "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 

永不退货。因此t他上传文件,但检查状态的代码永远不会返回。
的session.txt文件不会被删除,当我手动执行命令

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

它的确显示我的文件列表(因为ls命令)。

我有3个问题:

  1. 为什么它没有返回。从哪里开始调试?
  2. 是否有反正我可以上传文件并检查其状态(可能由 “put”命令后由ftp命令返回的错误代码)。
  3. 是否在代码中指定了错误的目录以上载 文件,cd命令失败,并且它不正确地将文件“放入” 根文件夹。检查文件上传的代码也一样。 我尝试了用

    .WriteLine "cd /Test" 
    

    和它的工作:所以 即使错了指定的目录中,该程序作为 成功

编辑1返回。该目录切换(两个文件夹深)导致问题?

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

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

是586493字节太多了吗?

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

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

控制台应用程序的输出和错误流共享相同的 内部4KB缓冲区。另外,WshScriptExec对象只有 提供对这些流的同步读取操作。同步 读操作引入了从这些流读取的调用脚本 与写入这些流的子流程之间的依赖关系,这可能会导致死锁情况。

+0

通过手动调用'FTP.EXE'并输入命令可能会更容易调试。从'ftp ftp.site.com'开始,它会询问您的用户名和密码,然后您只需按照该脚本进行操作即可。 –

+0

我知道验证文件是否正确上传的唯一方法是下载它,并将其与原始文件进行比较。为确保传输正确,您可以设置ASCII或BINARY开关,具体取决于它是文本还是二进制文件。这样做很简单,只需在传输文件之前发送文本“ascii”或“binary”即可。如果不这样做可能会导致意外的问题,因为ftp处理传输的方式不同。 –

+0

就像我说的,如果我手动运行命令,它将完全正常运行(在4.28秒内收到586493个字节)。问题在于VBS以某种方式不返回结果。我不知道从哪里开始调试。 –

回答

0

我相信问题是您从过程中读取stdout的方式。我使用这种技术成功地如下,对不起,我没有时间适应你的脚本并尝试一下,所以这取决于你。

以下执行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  
+0

即使您收到“回复来自”这并不意味着主机已启动:有时您会收到来自路由器的回复,通知您远程网络无法访问 – fthiella

+0

hi ftiela,这不是重点,如果你想知道如果一台电脑在线有更好的解决方案,我只是用它来显示标准输出的使用,并避免其他意见,没有这是不是使用它的方式,但它是可靠的和工作 – peter

+0

是的,我知道这不是重点,但在某些情况下,检查您是否有“回复来自”并不意味着主机已启动:回复来自路由器或您的主机(例如[http:// serverfault.com/questions/131136/ping-replies-from-same-computer-with-destination-host-unreachable-no-route](http://serverfault.com/questions/131136/ping-replies-from-same -computer-with-destination-host-unreachable-no-route)。我认为最好检查回复的状态,而不仅仅是“Rep来自“字符串。 – fthiella