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

Last modified: by martin