Checking file existence and timestamp
The following example checks an existence of a remote file and its timestamp. If the remote file exists and is newer than a local copy of the file or the local copy does not exist, the local copy is updated.
The code basically does what local to remote synchronization restricted to a single file (usign a file mask) would do with much less code (a corresponding code is shown in comments). The example can though be extended with more complex tests that a plain synchronization cannot do (like checksum comparison).
Advertisement
C# Example
using System; using System.Globalization; using System.IO; using WinSCP; class Example { public static int Main() { try { // Setup session options SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Sftp, HostName = "example.com", UserName = "user", Password = "mypassword", SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." }; using (Session session = new Session()) { // Connect session.Open(sessionOptions); string stamp = DateTime.Now.ToString("yyyyMMdd", CultureInfo.InvariantCulture); string fileName = "export_" + stamp + ".txt"; string remotePath = "/home/user/sysbatch/" + fileName; string localPath = @"d:\backup\" + fileName; // Manual "remote to local" synchronization. // You can achieve the same using: // session.SynchronizeDirectories( // SynchronizationMode.Local, localPath, remotePath, false, false, // SynchronizationCriteria.Time, // new TransferOptions { FileMask = fileName }).Check(); if (session.FileExists(remotePath)) { bool download; if (!File.Exists(localPath)) { Console.WriteLine( "File {0} exists, local backup {1} does not", remotePath, localPath); download = true; } else { DateTime remoteWriteTime = session.GetFileInfo(remotePath).LastWriteTime; DateTime localWriteTime = File.GetLastWriteTime(localPath); if (remoteWriteTime > localWriteTime) { Console.WriteLine( "File {0} as well as local backup {1} exist, " + "but remote file is newer ({2}) than local backup ({3})", remotePath, localPath, remoteWriteTime, localWriteTime); download = true; } else { Console.WriteLine( "File {0} as well as local backup {1} exist, " + "but remote file is not newer ({2}) than local backup ({3})", remotePath, localPath, remoteWriteTime, localWriteTime); download = false; } } if (download) { // Download the file and throw on any error session.GetFiles(remotePath, localPath).Check(); Console.WriteLine("Download to backup done."); } } else { Console.WriteLine("File {0} does not exist yet", remotePath); } } return 0; } catch (Exception e) { Console.WriteLine("Error: {0}", e); return 1; } } }
Advertisement
VB.NET Example
Imports System.Globalization Imports System.IO Imports WinSCP Friend Class Example Public Shared Function Main() As Integer Try ' Setup session options Dim sessionOptions As New SessionOptions With sessionOptions .Protocol = Protocol.Sftp .HostName = "example.com" .UserName = "user" .Password = "mypassword" .SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." End With Using session As New Session ' Connect session.Open(sessionOptions) Dim stamp As String = DateTime.Now.ToString("yyyyMMdd", CultureInfo.InvariantCulture) Dim fileName As String = "export_" & stamp & ".txt" Dim remotePath As String = "/home/user/sysbatch/" & fileName Dim localPath As String = "d:\backup\" & fileName ' Manual "remote to local" synchronization. ' You can achieve the same using: ' session.SynchronizeDirectories( ' SynchronizationMode.Local, localPath, remotePath, False, False, ' SynchronizationCriteria.Time, ' New TransferOptions With { .FileMask = fileName }).Check If session.FileExists(remotePath) Then Dim download As Boolean If Not File.Exists(localPath) Then Console.WriteLine( "File {0} exists, local backup {1} does not", remotePath, localPath) download = True Else Dim remoteWriteTime As DateTime = session.GetFileInfo(remotePath).LastWriteTime Dim localWriteTime As DateTime = File.GetLastWriteTime(localPath) If remoteWriteTime > localWriteTime Then Console.WriteLine( "File {0} as well as local backup {1} exist, " & "but remote file is newer ({2}) than " & "local backup ({3})", remotePath, localPath, remoteWriteTime, localWriteTime) download = True Else Console.WriteLine( "File {0} as well as local backup {1} exist, " & "but remote file is not newer ({2}) than " & "local backup ({3})", remotePath, localPath, remoteWriteTime, localWriteTime) download = False End If End If If download Then ' Download the file and throw on any error session.GetFiles(remotePath, localPath).Check() Console.WriteLine("Download to backup done.") End If Else Console.WriteLine("File {0} does not exist yet", remotePath) End If End Using Return 0 Catch e As Exception Console.WriteLine("Error: {0}", e) Return 1 End Try End Function End Class
Advertisement
PowerShell Example
Learn more about using WinSCP .NET assembly from PowerShell.
try { # Load WinSCP .NET assembly Add-Type -Path "WinSCPnet.dll" # Setup session options $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ Protocol = [WinSCP.Protocol]::Sftp HostName = "example.com" UserName = "user" Password = "mypassword" SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." } $session = New-Object WinSCP.Session try { # Connect $session.Open($sessionOptions) $stamp = Get-Date -Format "yyyyMMdd" $fileName = "export_$stamp.txt" $remotePath = "/home/user/sysbatch/$fileName" $localPath = "d:\backup\$fileName" # Manual "remote to local" synchronization. # You can achieve the same using: # $transferOptions = New-Object WinSCP.TransferOptions # $transferOptions.FileMask = $fileName # $session.SynchronizeDirectories( # [WinSCP.SynchronizationMode]::Local, $localPath, $remotePath, # $False, $False, [WinSCP.SynchronizationCriteria]::Time, # $transferOptions).Check() if ($session.FileExists($remotePath)) { if (!(Test-Path $localPath)) { Write-Host ( "File $remotePath exists, local backup $localPath does not") $download = $True } else { $remoteWriteTime = $session.GetFileInfo($remotePath).LastWriteTime $localWriteTime = (Get-Item $localPath).LastWriteTime if ($remoteWriteTime -gt $localWriteTime) { Write-Host ("File $remotePath as well as local backup $localPath exist, " + "but remote file is newer ($remoteWriteTime) than " + "local backup ($localWriteTime)") $download = $True } else { Write-Host ( "File $remotePath as well as local backup $localPath exist, " + "but remote file is not newer ($remoteWriteTime) than " + "local backup ($localWriteTime)") $download = $False } } if ($download) { # Download the file and throw on any error $session.GetFiles($remotePath, $localPath).Check() Write-Host "Download to backup done." } } else { Write-Host "File $remotePath does not exist yet" } } finally { # Disconnect, clean up $session.Dispose() } exit 0 } catch { Write-Host "Error: $($_.Exception.Message)" exit 1 }
Advertisement
JScript (WSH) Example
In this example the JScript script is embedded into WSF file, to allow access to enumeration values.
<job> <reference object="WinSCP.Session"/> <script language="JScript"> try { // Setup session options var sessionOptions = WScript.CreateObject("WinSCP.SessionOptions"); sessionOptions.Protocol = Protocol_Sftp; sessionOptions.HostName = "example.com"; sessionOptions.UserName = "user"; sessionOptions.Password = "mypassword"; sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..."; var session = WScript.CreateObject("WinSCP.Session"); try { // Connect session.Open(sessionOptions); var today = new Date(); var stamp = today.getFullYear() + (today.getMonth() + 1 < 10 ? "0" : "") + (today.getMonth() + 1) + (today.getDate() < 10 ? "0" : "") + today.getDate(); var fileName = "export_" + stamp + ".txt"; var remotePath = "/home/user/sysbatch/" + fileName; var localPath = "d:\\backup\\" + fileName; var fs = WScript.CreateObject("Scripting.FileSystemObject"); // Manual "remote to local" synchronization. // You can achieve the same using: // var transferOptions = WScript.CreateObject("WinSCP.TransferOptions"); // transferOptions.FileMask = fileName; // session.SynchronizeDirectories( // SynchronizationMode_Local, localPath, remotePath, false, false, // SynchronizationCriteria_Time, transferOptions).Check(); if (session.FileExists(remotePath)) { var download; if (!fs.FileExists(localPath)) { WScript.Echo( "File " + remotePath + " exists, local backup " + localPath + " does not"); download = true; } else { var remoteWriteTime = new Date(session.GetFileInfo(remotePath).LastWriteTime); var localWriteTime = fs.GetFile(localPath).DateLastModified; if (remoteWriteTime > localWriteTime) { WScript.Echo( "File " + remotePath + " as well as local backup " + localPath + " exist, but remote file is newer (" + remoteWriteTime + ") than " + "local backup (" + localWriteTime + ")"); download = true; } else { WScript.Echo( "File " + remotePath + " as well as local backup " + localPath + " exist, but remote file is not newer (" + remoteWriteTime + ") than " + "local backup (" + localWriteTime + ")"); download = false; } } if (download) { // Download the file and throw on any error session.GetFiles(remotePath, localPath).Check(); WScript.Echo("Download to backup done."); } } else { WScript.Echo("File " + remotePath + " does not exist yet"); } } finally { // Disconnect, clean up session.Dispose(); } } catch (e) { WScript.Echo("Error: " + e.message); WScript.Quit(1); } </script> </job>
Advertisement
VBScript (WSH) Example
In this example the VBScript script is embedded into WSF file, to allow access to enumeration values.
<job> <reference object="WinSCP.Session"/> <script language="VBScript"> Option Explicit ' Setup session options Dim sessionOptions Set sessionOptions = WScript.CreateObject("WinSCP.SessionOptions") With sessionOptions .Protocol = Protocol_Sftp .HostName = "example.com" .UserName = "user" .Password = "mypassword" .SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." End With Dim session Set session = WScript.CreateObject("WinSCP.Session") ' Connect session.Open sessionOptions Dim today, stamp today = Date stamp = Year(today) If Month(today) < 10 Then stamp = stamp & "0" End If stamp = stamp & Month(today) if Day(today) < 10 Then stamp = stamp & "0" End If stamp = stamp & Day(today) Dim fileName, remotePath, localPath fileName = "export_" & stamp & ".txt" remotePath = "/home/user/sysbatch/" & fileName localPath = "d:\backup\" & fileName Dim fs Set fs = WScript.CreateObject("Scripting.FileSystemObject") ' Manual "remote to local" synchronization. ' You can achieve the same using: ' Dim transferOptions ' Set transferOptions = WScript.CreateObject("WinSCP.TransferOptions") ' transferOptions.FileMask = fileName ' session.SynchronizeDirectories( _ ' SynchronizationMode_Local, localPath, remotePath, false, false, _ ' SynchronizationCriteria_Time, transferOptions).Check Dim download, remoteWriteTime, localWriteTime If session.FileExists(remotePath) Then If Not fs.FileExists(localPath) Then WScript.Echo "File " & remotePath & " exists, local backup " & localPath & " does not" download = True Else remoteWriteTime = CDate(session.GetFileInfo(remotePath).LastWriteTime) localWriteTime = fs.GetFile(localPath).DateLastModified If remoteWriteTime > localWriteTime Then WScript.Echo _ "File " & remotePath & " as well as local backup " & localPath & " exist, " & _ "but remote file is newer (" & remoteWriteTime & ") than " & _ "local backup (" & localWriteTime & ")" download = True Else WScript.Echo _ "File " & remotePath & " as well as local backup " & localPath & " exist, " & _ "but remote file is not newer (" & remoteWriteTime & ") than " & _ "local backup (" & localWriteTime & ")" download = False End If End If If download Then ' Download the file and throw on any error session.GetFiles(remotePath, localPath).Check() WScript.Echo "Download to backup done." End If Else WScript.Echo "File " & remotePath & " does not exist yet" End If ' Disconnect, clean up session.Dispose </script> </job>
Advertisement