2012-10-22 213 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