This is an old revision of the document!

Useful Scripts

Uploading a single file

A single file upload involves so few commands that it is enough to provide them on the command line, saving writing a script file:

winscp.com /command "option batch abort" "option confirm off" "open sftp://user:password@example.com/" "put examplefile.txt /home/user/" "exit"

However you may want to use a script file anyway, so you can later expand it:

option batch abort
option confirm off
open sftp://user:password@example.com/
put examplefile.txt /home/user/
exit

To run the script use following command (providing you have saved the script to file example.txt):

winscp.com /script=example.txt

Upload to multiple servers / Parametrized script

If you need to repeat the same task against multiple servers, instead of writing separate and almost identical scripts for each server, you can write one parametrized script.

Following example is parametrized script that accepts one parameter with session URL and uploads a fixed local file to a fixed remote directory:

option batch abort
option confirm off
open %1%
put examplefile.txt /home/user/
exit

To use the script against multiple servers, just execute the script (saved to file script.txt) repeatedly, using different session URL as parameter:

winscp.com /script=script.txt /parameter sftp://martin@server1.example.com/
winscp.com /script=script.txt /parameter sftp://test@server2.example.com/

If the script has also other variable parts, like file to upload or remote directory, just replace those parts with additional parameters (%2%, %3%, etc).

Alternative to using /parameter switch is using environment variable in the script.

Downloading file to timestamped-filename

Using WinSCP .NET Assembly

Use WinSCP .NET assembly from your favorite language. Use relevant construct of your language or API of your runtime environment for the file name formatting.

If you do not have your favorite language, use PowerShell:

param (
    $localPath = "c:\downloaded\",
    $remotePath = "/home/user/",
    $fileName = "download.txt"
)
         
try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "example.com"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "mypassword"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Format timestamp
        $stamp = $(Get-Date -f "yyyyMMddHHmmss")
 
        # Download the file and throw on any error
        $session.GetFiles(
            ($remotePath + $fileName),
            ($localPath + $fileName + "." + $stamp)).Check()
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

Using WinSCP Scripting

Using TIMESTAMP Variable

In the latest beta release, you can use %TIMESTAMP% construct to insert a real-time to a script.

option batch abort
option confirm off
open mysession
get "/home/user/download.txt" "C:\downloaded\download.txt.%TIMESTAMP#yyyymmddhhnnss%"
exit

From a Batch File

In Windows batch file, you may retrieve current time in locale-independent format using command wmic os get LocalDateTime. You can parse the value using using string processing syntax:

@echo off
 
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set LDT=%%j
set STAMP=%LDT:~0,4%%LDT:~4,2%%LDT:~6,2%%LDT:~8,2%%LDT:~10,2%%LDT:~12,2%
 
winscp.com /script=script.txt

Note that the expression after set STAMP= shows how to extract individual date/time components, in case you need to interleave them by some punctuation. If not, you can replace it by simple %LDT:~0,14%.

The script.txt should make use of the variable STAMP using %STAMP% syntax. For example:

option batch abort
option confirm off
open mysession
get "/home/user/download.txt" "C:\downloaded\download.txt.%STAMP%"
exit

From a JScript

You may use following Windows script host JScript code (example.js):

// Local path to download to (keep trailing slash)
var LOCALPATH = "c:\\downloaded\\";
// Remote path to download from (keep trailing slash)
var REMOTEPATH = "/home/user/";
// File to download
var FILE = "download.txt";
// Session to connect to
var SESSION = "session";
// Path to winscp.com
var WINSCP = "c:\\program files\\winscp\\winscp.com";
 
// helper function to pad zeroes to the left of number
function pad(n, len)
{
    var s = n.toString();
    while (s.length < len)
    {
        s = '0' + s;
    }
    return s;
}
 
var date = new Date();
 
// format timestamp
var stamp = 
    pad(date.getFullYear(), 4) +
    pad(date.getMonth(), 2) +
    pad(date.getDate(), 2) +
    pad(date.getHours(), 2) +
    pad(date.getMinutes(), 2) +
    pad(date.getSeconds(), 2);
 
var shell = WScript.CreateObject("WScript.Shell");
 
// run winscp to download the file into timestamped-filename
exec = shell.Exec("\"" + WINSCP + "\"");
exec.StdIn.Write(
    "option batch abort\n" +
    "open \"" + SESSION + "\"\n" +
    "get \"" + REMOTEPATH + FILE + "\" \"" + LOCALPATH + FILE + "." + stamp + "\"\n" +
    "exit\n");
 
// wait until it finishes and collect its output
var output = exec.StdOut.ReadAll();
// optionally print the output
WScript.Echo(output);

Run the script with command:

cscript /nologo example.js

Downloading the most recent file

Using WinSCP .NET Assembly

Use WinSCP .NET assembly from your favorite language.

If you do not have your favorite language, use PowerShell:

param (
    $localPath = "c:\downloaded\",
    $remotePath = "/home/user/"
)
 
try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "example.com"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "mypassword"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Gel list of files in the directory
        $directoryInfo = $session.ListDirectory($remotePath)
 
        # Select the most recent file
        $latest =
            $directoryInfo.Files |
            Where-Object { -Not $_.IsDirectory } |
            Sort-Object LastWriteTime -Descending |
            Select-Object -First 1
 
        # Any file at all?
        if ($latest -eq $Null)
        {
            Write-Host "No file found"
            exit 1
        }
 
        # Download the selected file
        $session.GetFiles($session.EscapeFileMask($remotePath + $latest.Name), $localPath).Check()
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

Using WinSCP Scripting

You may use following Windows script host JScript code (example.js):

// Configuration
 
// Local path to download to (keep trailing slash)
var LOCALPATH = "c:\\downloaded\\";
// Remote path to search in (keep trailing slash)
var REMOTEPATH = "/home/user/";
// Mask of files to search for
var FILEMASK = "*.*";
// Session to connect to
var SESSION = "session";
// Path to winscp.com
var WINSCP = "c:\\program files\\winscp\\winscp.com";
 
var filesys = WScript.CreateObject("Scripting.FileSystemObject");
var shell = WScript.CreateObject("WScript.Shell");
   
var logfilepath = filesys.GetSpecialFolder(2) + "\\" + filesys.GetTempName() + ".xml";
 
var exec;
 
// run winscp to get list of file in the remote directory into XML log
exec = shell.Exec("\"" + WINSCP + "\" /xmllog=\"" + logfilepath + "\"");
exec.StdIn.Write(
    "option batch abort\n" +
    "open \"" + SESSION + "\"\n" +
    "ls \"" + REMOTEPATH + FILEMASK + "\"\n" +
    "exit\n");
 
// wait until it finishes and collect its output
var output = exec.StdOut.ReadAll();
// optionally print the output
WScript.Echo(output);
 
if (exec.ExitCode != 0)
{
    WScript.Echo("Error retrieving list of files");
    WScript.Quit(1);
}
 
// look for log file
var logfile = filesys.GetFile(logfilepath);
 
if (logfile == null)
{
    WScript.Echo("Cannot find log file");
    WScript.Quit(1);
}
 
// parse XML log file
var doc = new ActiveXObject("MSXML2.DOMDocument");
doc.async = false;
doc.load(logfilepath);
 
doc.setProperty("SelectionNamespaces", 
    "xmlns:w='http://winscp.net/schema/session/1.0'");
 
var nodes = doc.selectNodes("//w:file");
 
// find the latest file
var filenameLatest = null;
var modificationLatest = null;
for (var i = 0; i < nodes.length; ++i)
{
    var filename = nodes[i].selectSingleNode("w:filename/@value");
    var modification = nodes[i].selectSingleNode("w:modification/@value");
    if ((filename != null) &&
        (filename.value != ".") &&
        (filename.value != "..") &&
        (modification != null))
    {
        // can compare timestamps stringwise
        if ((modificationLatest == null) ||
            (modificationLatest < modification.value))
        {
            modificationLatest = modification.value;
            filenameLatest = filename.value;
        }
    }
}
 
// no file in the log
if (filenameLatest == null)
{
    WScript.Echo("No file found");
    WScript.Quit(0);
}
 
// run winscp to download the latest file
exec = shell.Exec("\"" + WINSCP + "\"");
exec.StdIn.Write(
    "option batch abort\n" +
    "option confirm off\n" +
    "open \"" + SESSION + "\"\n" +
    "get \"" + REMOTEPATH + filenameLatest + "\" \"" + LOCALPATH + "\"\n" +
    "exit\n");
 
// wait until it finishes and collect its output
var output = exec.StdOut.ReadAll();
// optionally print the output
WScript.Echo(output);
 
if (exec.ExitCode != 0)
{
    WScript.Echo("Error downloading " + filenameLatest);
    WScript.Quit(1);
}

Run the script with command:

cscript /nologo example.js

Alternatives

Some of following alternatives can be easier to implement or actually even more appropriate for your specific task:

  • Synchronizing a remote directory to a local directory (using synchronize local in scripting or Session.SynchronizeDirectories(SynchronizationMode.Local, …) in .NET assembly);
  • Downloading all files created in the last 24 hours (using file mask *>=1D; e.g. get -filemask="*>=1D" /home/user/*, or an equivalent in .NET assembly).
  • Downloading all files created today (using %TIMESTAMP% syntax to format file mask with today’s time constraint, e.g. get -filemask="*>=%TIMESTAMP#yyyy-mm-dd%" /home/user/*, or an equivalent in .NET assembly).

Uploading the most recent file

Using WinSCP .NET Assembly

Use WinSCP .NET assembly from your favorite language.

If you do not have your favorite language, use PowerShell:

try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "example.com"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "mypassword"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        $localPath = "c:\toupload\"
        $remotePath = "/home/user/"
 
        # Gel list of files in the directory
        $directoryInfo = $session.ListDirectory($remotePath)
 
        # Select the most recent file.
        # The !$_.PsIsContainer test excludes subdirectories.
        # With PowerShell 3.0, you can replace this with -File switch of Get-ChildItem. 
        $latest =
            Get-ChildItem -Path $localPath |
            Where-Object {!$_.PsIsContainer} |
            Sort-Object LastWriteTime -Descending |
            Select-Object -First 1
 
        # Any file at all?
        if ($latest -eq $Null)
        {
            Write-Host "No file found"
            exit 1
        }
 
        # Upload the selected file
        $session.PutFiles($session.EscapeFileMask($localPath + $latest.Name), $remotePath).Check()
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

Using WinSCP Scripting

You may use following batch file that calls WinSCP script:1

@echo off
set SESSION=sftp://user:password@example.com/
set LOCAL_PATH=c:\toupload\
set REMOTE_PATH=/home/user/
 
for /f "delims=" %%i in ('dir /b /od %LOCAL_PATH%\*') do set LATEST=%%i
if "%LATEST%" == "" goto NO_FILE
 
winscp.com /command ^
    "option batch abort" ^
    "option confirm off" ^
    "open %SESSION%" ^
    "put %LOCAL_PATH%%LATEST% %REMOTE_PATH%" ^
    "exit"
exit %ERRORLEVEL%
 
:NO_FILE
echo No file found
exit 1

Alternatives

Some of following alternatives can be easier to implement or actually even more appropriate for your specific task:

Checking file existence

Remote file existence

Using WinSCP .NET Assembly

Use method Session.FileExists from WinSCP .NET assembly.

If you do not have your favorite language, use PowerShell:

$remotePath = "/home/user/test.txt"
 
if ($session.FileExists($remotePath))
{
    Write-Host ("File {0} exists" -f $remotePath)
}

See complete PowerShell example for Session.FileExists.

If you are not looking for a specific file, but for any file matching a mask (e.g. *.txt), you need to use Session.ListDirectory and query returned list of files.

Advertisement

Using WinSCP Scripting

You can use a stat command in option batch abort mode to query file attributes. If the file does not exist, the stat command fails and so does the script. Then, test WinSCP exit code to determine, if the file exists or not.

@echo off
 
set REMOTE_PATH=/home/user/test.txt
winscp.com /command ^
    "option batch abort" ^
    "open mysession" ^
    "stat %REMOTE_PATH%" ^
    "exit"
 
if %ERRORLEVEL% neq 0 goto error
 
echo File %REMOTE_PATH% exists
rem Do something
exit 0
 
:error
echo Error or file %REMOTE_PATH% not exists
exit 1

Local file existence

Moving local files to different location after successful upload

Using WinSCP .NET Assembly

Use WinSCP .NET assembly from your favorite language.

If you do not have your favorite language, use PowerShell:

param (
    $localPath = "C:\upload\*",
    $remotePath = "/home/user/",
    $backupPath = "C:\backup\"
)
 
try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "example.com"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "mypassword"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Upload files, collect results
        $transferResult = $session.PutFiles($localPath, $remotePath)
 
        # Iterate over every transfer
        foreach ($transfer in $transferResult.Transfers)
        {
            # Success or error?
            if ($transfer.Error -eq $Null)
            {
                Write-Host ("Upload of {0} succeeded, moving to backup" -f
                    $transfer.FileName)
                # Upload succeeded, move source file to backup
                Move-Item $transfer.FileName $backupPath
            }
            else
            {
                Write-Host ("Upload of {0} failed: {1}" -f
                    $transfer.FileName, $transfer.Error.Message)
            }
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

Using WinSCP Scripting

WinSCP scripting does not support move command for local files. Instead you can combine WinSCP script with batch file:

option batch abort
option confirm off
# Connect
open mysession
# Upload the files
put *.*

Launch the above script from batch file like the one below:

winscp.com /script=example.txt
if %ERRORLEVEL% neq 0 goto error
 
echo Upload succeeded, moving local files
move *.* c:\backup\
exit 0
 
:error
echo Upload failed, keeping local files
exit 1

Locking files while uploading / Upload to temporary file name

You may have an automated system monitoring a remote folder and you want to prevent it from accidentally picking a file that has not finished uploading yet. As majority of SFTP and FTP servers do not support file locking (and neither does WinSCP), you need to prevent the automated system from picking the file otherwise.

Common workarounds are:

  1. Upload “done” file once an upload of data files finishes and have the automated system wait for the “done” file before processing the data files. This is easy solution, but won’t work in multi-user environment.
  2. Upload data files to temporary (“upload”) folder and move them atomically to target folder once the upload finishes.
  3. Upload data files to distinct temporary name, e.g. with .filepart extension, and rename them atomically once the upload finishes. Have the automated system ignore the .filepart files.

Here we focus on the third approach (although the second is very similar, implementation-wise).

Using Transfer to temporary filename feature

With SFTP protocol, you can use Transfer to temporary filename feature to have WinSCP handle the rename automatically for you.

In scripting, use:

put -resumesupport=on d:\toupload\*.txt /home/martin/upload/

With WinSCP .NET assembly, use:

$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::On
$session.PutFiles("d:\toupload\*.txt", "/home/martin/upload/", $False, $transferOptions).Check()

Moving/renaming uploaded files when upload finishes

If you need to use a different name pattern or a protocol different from SFTP or you want to take the second approach, you need to code the rename/move.

Following example shows implementation of the third approach using WinSCP .NET assembly in PowerShell:

param (
    $localPath = "c:\toupload\",
    $remotePath = "/home/user/upload/"
)
 
try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "example.com"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "mypassword"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Deliberately using an underscore instead of a dot,
        # as the dot has specific meaning in operation mask
        $suffix = "_filepart"
 
        $transferOptions = New-Object WinSCP.TransferOptions
        # Particularly with SFTP protocol, prevent additional .filepart suffix
        # from being added to uploaded files larger than 100 KB
        $transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
 
        # Upload all .txt files with temporary "_filepart" suffix
        $transferResult =
            $session.PutFiles(($localPath + "*.txt"), ($remotePath + "*.*" + $suffix),
                $False, $transferOptions)
 
        # Throw on any error
        $transferResult.Check()
 
        # Rename uploaded files
        foreach ($transfer in $transferResult.Transfers)
        {
            # Remove suffix
            $finalName = $transfer.Destination.SubString(0, $transfer.Destination.Length - $suffix.Length)
            Write-Host ("Renaming uploaded file {0} to final name {1}" -f $transfer.Destination, $finalName)
            # Rename uploaded file to its final name
            $session.MoveFile($transfer.Destination, $finalName)
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

Shortcut to synchronize any local directory with remote directory

You may want to have a script that synchronizes any local directory with a same-named subdirectory of fixed remote path, e.g.:

  • c:\www\gallery with /home/user/www/gallery;
  • c:\users\username\www\forum with /home/user/www/forum.

Such a script is particularly useful for integrating with Windows Explorer’s ‘Send To’ menu.

First create wrapper batch file to store the paths you want to synchronize into environment variables (change /home/user/www/ to remote path root you want to synchronize against):

winscp.com /script=example.txt /parameter %1 "/home/user/www/%~n1%~x1"

The script example.txt may look like:

# Being intended for interactive session, we are not enabling batch mode
# Connect
open mysession
# Synchronize paths provided via environment variables
synchronize remote "%1%" "%2%"

Then you can make a shortcut to the batch file:

  • When placed on desktop, you can drop any local directory to it to start synchronization;
  • When placed to C:\Users\username\AppData\Roaming\Microsoft\Windows\SendTo, you can use Send To > Your Shortcut from context menu of any local directory.

Automatically compress files before download

Following script compresses selected files into tar/gzip archive and downloads it:

option batch abort
option confirm off
open mysession
cd %1%
call tar -czf /tmp/archive.tar.gz %2%
lpwd
get -delete /tmp/archive.tar.gz
exit

Launch the above script from batch file like the one below, which automatically decompresses the archive:

winscp.com /script=example.txt /parameter %*
if %ERRORLEVEL% neq 0 goto error
 
echo Retrieving files succeeded
gzip -d archive.tar.gz
tar -xf archive.tar
del archive.tar
exit 0
 
:error
echo Retrieving files failed
exit 1

Example of running the batch file to download all files under /home/user/www:

example.bat /home/user/www *.*

The batch file needs Windows ports of gzip and tar tools. You can get them from UnxUtils project.

Running WinSCP from VB.NET

WinSCP .NET assembly mostly deprecates techniques demostrated in this article. Using the assembly is now preferred approach for advanced automation tasks with WinSCP.

Following is more robust alternative to simple example contained in guide to SFTP file transfers in .NET.

Imports System
Imports System.IO
Imports System.Diagnostics
Imports System.Xml
Imports System.Xml.XPath
Imports System.Configuration.ConfigurationManager
 
Public Class SFTP
    ' SFTP support, built on WinSCP
    Public Shared Function PutSFTP(ByRef filename As String, ByRef remotehost As String, ByRef username As String, ByRef password As String, _
                           Optional ByVal outfilename As String = Nothing, Optional ByVal output As String = Nothing,
                           Optional ByRef errmsg As String = Nothing) As Boolean
 
        ' Run hidden WinSCP process
        Dim winscp As Process = New Process()
        Dim logname As String = Path.ChangeExtension(Path.GetTempFileName, "xml")
        With winscp.StartInfo
            ' SFTPExecutable needs to be defined in app.config to point to winscp.com
            Try
                .FileName = AppSettings("SFTPExecutable")
                If .FileName Is Nothing OrElse .FileName.Length = 0 Then Throw (New Exception("from PutSFTP: SFTPExecutable not set in config file."))
            Catch ex As Exception
                errmsg = ex.Message
                Return False
            End Try
            .Arguments = "/xmllog=" + logname
            .UseShellExecute = False
            .RedirectStandardInput = True
            .RedirectStandardOutput = True
            .CreateNoWindow = True
        End With
        Try
            winscp.Start()
        Catch ex As Exception
            errmsg = "from PutSFTP:  Could not run the WinSCP executable " & winscp.StartInfo.FileName & Environment.NewLine & ex.Message
            Return False
        End Try
 
        ' Feed in the scripting commands
        With winscp.StandardInput
            .WriteLine("option batch abort")
            .WriteLine("option confirm off")
            .WriteLine("open sftp://" & username & ":" & password & "@" & remotehost & "/")
            If outfilename Is Nothing Then .WriteLine("put " & filename) Else .WriteLine("put " & filename & " """ & outfilename & """")
            .Close()
        End With
        If output IsNot Nothing Then output = winscp.StandardOutput.ReadToEnd()
 
        ' Wait until WinSCP finishes
        winscp.WaitForExit()
 
        ' Parse and interpret the XML log
        ' (Note that in case of fatal failure the log file may not exist at all)
        If Not File.Exists(logname) Then
            errmsg = "from PutSFTP:  The WinSCP executable appears to have crashed."
            Return False
        End If
 
        Dim log As XPathDocument = New XPathDocument(logname)
        Dim ns As XmlNamespaceManager = New XmlNamespaceManager(New NameTable())
        ns.AddNamespace("w", "http://winscp.net/schema/session/1.0")
        Dim nav As XPathNavigator = log.CreateNavigator()
 
        ' Success (0) or error?
        Dim status As Boolean = (winscp.ExitCode = 0)
        If Not status Then
            errmsg = "from PutSFTP:  There was an error transferring " & filename & "."
            ' See if there are any messages associated with the error
            For Each message As XPathNavigator In nav.Select("//w:message", ns)
                errmsg &= Environment.NewLine & message.Value
            Next message
        End If
 
        Try
            My.Computer.FileSystem.DeleteFile(logname)
        Catch ex As Exception
            ' at least we tried to clean up
        End Try
 
        Return status
    End Function
End Class

<trailer>

Further Reading

</trailer>

<nosplit>

Other Examples

</nosplit>

  1. Inspired by SuperUser question Upload only the latest file with WinSCP.Back

Last modified: by martin