(原创)利用Winscp软件同步本地或远程的文件(二)

上一篇讲过如何利用winscp脚本同步本地或远程的文件,但实际使用过程中遇到一个问题,
Winscp只能同步指定目录下所有文件(包括子目录),可以通过VBS动态生成脚本文件,但也只能同步一个指定目录所有文件.如果想要同步目录中的个别文件,比如说同步所有目录中修改日期为某一天的文件或者特定名称的文件时,利用winscp脚本就没有办法解决这个问题,这时就需要我们去写程序解决该问题了.我觉得还是自己去写一个FTP组件才能满足特定的要求.

一, 我先讲一下如何利用VBS动态生成脚本文件
遇到问题: 如果脚本中指定的远程目录不存在,程序会自动将根目录下的所有文件都同步过来.

配置文件syscfg.xml <?xml version="1.0" encoding="utf-8"?>
<Root>
  <PubDate></PubDate>
  <Companys>
    <Company>
      <Name>alcatel</Name>
      <FTPConnection>ftp://user1:password1@ftp.test.com:21</FTPConnection>
      <LocalDirectory>E:\test\Postion\XmlFile_Source\34091</LocalDirectory>
      <RemoteDirectory>/Position</RemoteDirectory>
      <SynchronizeWay>local</SynchronizeWay>
      <NeedDate>false</NeedDate>
      <DateStyle>yyyy-mm-dd</DateStyle>
    </Company>
 <Company>
      <Name>Fosun</Name>
      <FTPConnection>ftp://user2:password2@ftp.test.com:21</FTPConnection>
      <LocalDirectory>E:\test\Postion\XmlFile_Source\384821</LocalDirectory>
      <RemoteDirectory>/Position</RemoteDirectory>
      <SynchronizeWay>local</SynchronizeWay>
      <NeedDate>false</NeedDate>
      <DateStyle>yyyy-mm-dd</DateStyle>
    </Company>
  </Companys>
</Root>

脚本模板文件

# winscp.exe /console /script=sample.txt

# Automatically answer all prompts negatively not to stall
# the script on errors
# option echo  on|off
option echo off

# option batch on|off|abort|continue
option batch on

# option confirm  on|off
option confirm off

# option transfer  binary|ascii|automatic
# option synchdelete  on|off
# option exclude clear | <mask>[;<mask2>...]
# option include clear | <mask>[;<mask2>...]

# open [ sftp|ftp|scp:// ][ <user> [ :password ] @ ] <host> [ :<port> ]
# open user:password@example.com
# Connect
open [%%FTPConnection%%]

# Change remote directory
# cd /home/user
cd [%%RemoteDirectory%%]

# Change local directory
# set to Degussa's working dir
lcd [%%LocalDirectory%%]

# Force binary mode transfer
option transfer binary

# Download file to the local directory d:\
# get examplefile.txt d:\

# option synchdelete  on|off
option synchdelete off

# option include clear | <mask>[;<mask2>...]
# option include /2008-*-*/;/2009-*-*/;/2010-*-*/;/2011-*-*/;/2012-*-*/;/2013-*-*/

# synchronize local|remote|both [ <local directory> [ <remote directory> ] ]
synchronize [%%Way%%]

# Disconnect
close

# Exit WinSCP
exit


  download.vbs

Option Explicit

Dim PubDate '处理某一天数据
Dim CompanyList '多个公司配置列表
Dim shell, strRootPath, strCommand
Dim strCfgFilePath, DataFolder, LogFolder

Set shell = CreateObject("Wscript.Shell")
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")

'当前程序运行目录
strRootPath = Left(Wscript.scriptFullName, InstrRev(Wscript.scriptFullName, "\"))
'WINSCP脚本文件目录
DataFolder = strRootPath & "Data"
If Not objFSO.FolderExists(DataFolder) Then
 objFSO.CreateFolder(DataFolder)
End If
'日志目录
LogFolder = strRootPath & "Log"
If Not objFSO.FolderExists(LogFolder) Then
 objFSO.CreateFolder(LogFolder)
End If

'配置文件路径
strCfgFilePath = strRootPath & "syscfg.xml"
'读取配置文件
If Not ReadCfg(strCfgFilePath) Then
 mLog "配置文件出错,请检查!"
End If

Dim intX
Dim strFile

For intX = 0 To UBound(CompanyList)-1
 If Len(CompanyList(intX,1)) > 0 Then
  strFile = UpdateWinscpScript(CompanyList(intX,0), CompanyList(intX,1), CompanyList(intX,2), CompanyList(intX,3), CompanyList(intX,4))
  If Len(strFile) <> 0 Then 
   mLog "Shell.run(winscp /console /script=" & strFile & ")"
   Shell.run("winscp /console /script=" & strFile)
  End If
 Else
  Exit For
 End If
Next

'生成Winscp脚本文件
Function UpdateWinscpScript(name, ftp, localDir, remoteDir, syschronizeWay)
 Dim strFilePath, strTemplatePath
 strFilePath = DataFolder & "/" & name & ".txt"
 strTemplatePath = strRootPath & "template.txt"

 If Not objFSO.FileExists(strTemplatePath) Then
  mLog "脚本模板文件不存在!(" & strTemplatePath & ")"
  UpdateWinscpScript = ""
  Exit Function
 End If

 '如果文件存在,先删除文件
 If objFSO.FileExists(strFilePath) Then
  objFSO.DeleteFile(strFilePath)
 End If

 '读取模板文件
 Dim strAllText
 Dim file
 On Error Resume Next
 Set file = objFSO.OpenTextFile(strTemplatePath)
 If Not file.AtEndOfStream Then
  strAllText = file.ReadAll
 End If
 file.Close
 If Err.Number <> 0 Then
  mLog "[UpdateWinscpScript][ERROR]" & Err.Description
  Err.Clear
 End If

 If Len(strAllText) = 0 Then
  mLog "[UpdateWinscpScript][ERROR]模板文件无内容,请检查!"
  UpdateWinscpScript = ""
  Exit Function
 End If

 Set file = objFSO.CreateTextFile(strFilePath)
 strAllText = Replace(strAllText, "[%%FTPConnection%%]", ftp)
 strAllText = Replace(strAllText, "[%%RemoteDirectory%%]", remoteDir)
 strAllText = Replace(strAllText, "[%%LocalDirectory%%]", localDir)
 strAllText = Replace(strAllText, "[%%Way%%]", syschronizeWay)
 file.write strAllText
 file.close
 If Err.Number <> 0 Then
  mLog "[UpdateWinscpScript][ERROR]" & Err.Description
  UpdateWinscpScript = ""
  Exit Function
 End If
 UpdateWinscpScript = strFilePath
End Function

'读取配置文件
Function ReadCfg(cfgFilePath)
 on Error resume next
 Dim fso
 set fso = CreateObject("Scripting.FileSystemObject") 
 '如果没有找到配置文件,退出Function
 If Not fso.FileExists(cfgFilePath) Then
  ReadCfg = false
  Exit Function
 End If

 Dim XmlDoc
 Dim rootNode
 Set XmlDoc = CreateObject("Microsoft.XMLDOM")
 If XmlDoc.load(cfgFilePath) Then
  '加载文件成功
  Set rootNode = XmlDoc.documentElement
  PubDate = Trim(rootNode.selectSingleNode("PubDate").text)
  If Len(PubDate) = 0 Then
   PubDate = date
  Else
   PubDate = CDate(PubDate)
  End If
  If Err.Number <> 0 Then
   mLog "[ReadCfg][ERROR]" & Err.Description
   Err.Clear
  End If
  Dim i, j
  i = 0
  Dim strRemotePath, strLocalPath, company
  Dim CompanyCount
  CompanyCount = rootNode.selectNodes("Companys/Company").length
  Redim CompanyList(CompanyCount, 7)
  for each company in rootNode.selectNodes("Companys/Company")   
   strRemotePath = ""
   mLog "***************************************************"
   'Name
   CompanyList(i,0) = company.selectSingleNode("Name").text
   mLog "Name: " & CompanyList(i,0)
   'FTPConnection
   CompanyList(i,1) = company.selectSingleNode("FTPConnection").text
   mLog "FTP: " & CompanyList(i,1)
      
   'SynchronizeWay
   CompanyList(i,4) = company.selectSingleNode("SynchronizeWay").text
   mLog "SynchronizeWay: " & CompanyList(i,4)
   'NeedDate
   CompanyList(i,5) = company.selectSingleNode("NeedDate").text
   mLog "NeedDate: " & CompanyList(i,5)
   'DateStyle
   CompanyList(i,6) = company.selectSingleNode("DateStyle").text
   mLog "DateStyle: " & CompanyList(i,6)
   
   'LocalDirectory
   strLocalPath = Trim(company.selectSingleNode("LocalDirectory").text)
   If Len(strLocalPath) > 0 Then    
    If Right(strLocalPath,1)="\" Then
     strLocalPath = Left(strLocalPath,instrRev(strLocalPath,"\")-1)
    End If
    If CompanyList(i,5) Then
     strLocalPath = GetPathWithDate(strLocalPath, PubDate, CompanyList(i,6), "\")
    End If
    If Not fso.FolderExists(strLocalPath) Then
     CreateDirectory strLocalPath, "\"
    End If
    CompanyList(i,2) = strLocalPath
   End If
   mLog "Local Directory: " & CompanyList(i,2)
   If Err.Number <> 0 Then
    mLog "[ReadCfg][ERROR]" & Err.Description
    Err.Clear
   End If
   'RemoteDirectory
   strRemotePath = Trim(company.selectSingleNode("RemoteDirectory").text)
   '去掉路径后面的/
   If Right(strRemotePath,1)="/" Then
    CompanyList(i,3) = Left(strRemotePath,instrRev(strRemotePath,"/")-1)
   Else
    CompanyList(i,3) = strRemotePath
   End If
   If CompanyList(i,5) Then
    CompanyList(i,3) = GetPathWithDate(CompanyList(i,3), PubDate, CompanyList(i,6), "/")
   End If
   mLog "Remote Directory: " & CompanyList(i,3)

   i = i + 1
  Next
  ReadCfg = True
 Else
  '加载文件失败
  ReadCfg = False
 End If
End Function

'返回带日期的远程目录
Function GetPathWithDate(strDir, strDate, strStyle, seperator)
 On Error Resume Next
 If len(year(strDate)) = 0 Then
  strDate = Date
 End If
 select case Lcase(strStyle)
 case "yyyy-mm-dd"
  GetPathWithDate = strDir & seperator & year(strDate) & "-" & Right("0"&Month(strDate),2) & "-" & Right("0"&Day(strDate),2)
 case "yyyy_mm_dd"
  GetPathWithDate = strDir & seperator & year(strDate) & "_" & Right("0"&Month(strDate),2) & "_" & Right("0"&Day(strDate),2)
 case "yyyymmdd"
  GetPathWithDate = strDir & seperator & year(strDate) & Right("0"&Month(strDate),2) & Right("0"&Day(strDate),2)
 case "yyyy-m-d"
  GetPathWithDate = strDir & seperator & year(strDate) & "-" & Month(strDate) & "-" & Day(strDate)
 Case "yyyy_m_d"
  GetPathWithDate = strDir & seperator & year(strDate) & "_" & Month(strDate) & "_" & Day(strDate)
 Case "yyyymd"
  GetPathWithDate = strDir & seperator & year(strDate) & Month(strDate) & Day(strDate)
 End Select
End Function


'创建本地目录
Sub CreateDirectory(dir, seperator)
 On Error Resume Next
 Dim fso
 Set fso = CreateObject("Scripting.FileSystemObject")
 Dim path
 path = ""
 Dim i
 Dim arrDir
 arrDir = split(dir, seperator)
 for i = 0 to UBound(arrDir)
  path = path & arrDir(i) & seperator
  If Not fso.FolderExists(path) Then
   fso.CreateFolder(path)
  End If
  If Err.Number <> 0 Then
   mLog "[CreateDirectory][ERROR]" & Err.Description
   Err.Clear
  End If
 Next
End Sub

' 记录日志
Private Function mLog(info)
   Dim logFile, dt, yyyy, mm, dd
   dt = Now
   yyyy = Year(dt)
   mm = Month(dt)
   dd = Day(dt)
   If Len(mm)=1 Then
      mm = "0" & mm
   End If
   If Len(dd)=1 Then
      dd = "0" & dd
   End If
   dt = yyyy & "-" & mm & "-" & dd & " " & Time()
   Do
  On Error Resume Next
  Err.Clear
  Set logfile = objFSO.OpenTextFile(LogFolder & "\" & yyyy & mm & dd & ".log", 8, True)
  WScript.Sleep(10)
   Loop Until not(Err.Number<>0)
   logFile.WriteLine dt & "->" & info
   logFile.Close()
   WScript.Echo dt & "->" & info  
End Function

转载于:https://www.cnblogs.com/anny-1980/articles/1157782.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值