This is an old revision of the document!
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 orSession.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).