Differences
This shows you the differences between the selected revisions of the page.
script_download_most_recent_file 2015-03-06 | script_download_most_recent_file 2022-06-16 (current) | ||
Line 2: | Line 2: | ||
===== [[library]] Using WinSCP .NET Assembly ===== | ===== [[library]] Using WinSCP .NET Assembly ===== | ||
+ | |||
+ | ==== [[powershell]] PowerShell ==== | ||
The following example uses [[library|WinSCP .NET assembly]] from a [[library_powershell|PowerShell]] script. If you have another preferred language, you can easily translate it. | The following example uses [[library|WinSCP .NET assembly]] from a [[library_powershell|PowerShell]] script. If you have another preferred language, you can easily translate it. | ||
<code powershell> | <code powershell> | ||
param ( | param ( | ||
- | $localPath = "c:\downloaded\", | + | $localPath = "c:\downloaded", |
- | $remotePath = "/home/user/" | + | $remotePath = "/home/user" |
) | ) | ||
Line 16: | Line 18: | ||
# Setup session options | # Setup session options | ||
- | $sessionOptions = New-Object WinSCP.SessionOptions | + | $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ |
- | ···$sessionOptions.Protocol = [WinSCP.Protocol]::Sftp | + | ········Protocol = [WinSCP.Protocol]::Sftp |
- | $sessionOptions.HostName = "example.com" | + | ·······HostName = "example.com" |
- | $sessionOptions.UserName = "user" | + | ·······UserName = "user" |
- | $sessionOptions.Password = "mypassword" | + | ·······Password = "mypassword" |
- | $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" | + | ·······SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." |
+ | } | ||
$session = New-Object WinSCP.Session | $session = New-Object WinSCP.Session | ||
Line 48: | Line 51: | ||
# Download the selected file | # Download the selected file | ||
- | $session.GetFiles($session.EscapeFileMask($remotePath + $latest.Name), $localPath).Check() | + | $session.GetFileToDirectory($latest.FullName, $localPath) | Out-Null |
} | } | ||
finally | finally | ||
Line 58: | Line 61: | ||
exit 0 | exit 0 | ||
} | } | ||
- | catch [Exception] | + | catch |
{ | { | ||
- | Write-Host $_.Exception.Message | + | Write-Host "Error: $($_.Exception.Message)" |
exit 1 | exit 1 | ||
} | } | ||
</code> | </code> | ||
- | ===== Using WinSCP Scripting ===== | + | ==== [[csharp]] C# ==== |
- | You may use following [[guide_automation_advanced#wsh|Windows script host JScript code]] (''example.js''): | + | |
- | <code javascript> | + | <code csharp> |
- | // Configuration | + | using System; |
+ | using System.Linq; | ||
+ | using WinSCP; | ||
- | // Local path to download to (keep trailing slash) | + | class Program |
- | var LOCALPATH = "c:\\downloaded\\"; | + | { |
- | // Remote path to search in (keep trailing slash) | + | ····static int Main(string[] args) |
- | var REMOTEPATH = "/home/user/"; | + | ····{ |
- | // Mask of files to search for | + | ········try |
- | var FILEMASK = "*.*"; | + | ········{ |
- | // Session to connect to | + | ············// Setup session options |
- | var SESSION = "session"; | + | SessionOptions sessionOptions = new SessionOptions |
- | // Path to winscp.com | + | { |
- | var WINSCP = "c:\\program files\\winscp\\winscp.com"; | + | ···············Protocol = Protocol.Sftp, |
+ | ················HostName = "example.com", | ||
+ | ···············UserName = "user", | ||
+ | ···············Password = "mypassword", | ||
+ | ···············SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...", | ||
+ | }; | ||
- | var filesys = WScript.CreateObject("Scripting.FileSystemObject"); | + | using (Session session = new Session()) |
- | var shell = WScript.CreateObject("WScript.Shell"); | + | { |
- | ·· | + | ···············// Connect |
- | var logfilepath = filesys.GetSpecialFolder(2) + "\\" + filesys.GetTempName() + ".xml"; | + | ···············session.Open(sessionOptions); |
- | var exec; | + | const string remotePath = "/home/user"; |
+ | const string localPath = @"C:\downloaded"; | ||
- | // run winscp to get list of file in the remote directory into XML log | + | ················// Get list of files in the directory |
- | exec = shell.Exec("\"" + WINSCP + "\" /xmllog=\"" + logfilepath + "\""); | + | ···············RemoteDirectoryInfo directoryInfo = session.ListDirectory(remotePath); |
- | exec.StdIn.Write( | + | |
- | "option batch abort\n" + | + | |
- | "open \"" + SESSION + "\"\n" + | + | |
- | "ls \"" + REMOTEPATH + FILEMASK + "\"\n" + | + | |
- | "exit\n"); | + | |
- | // wait until it finishes and collect its output | + | ················// Select the most recent file |
- | var output = exec.StdOut.ReadAll(); | + | ················RemoteFileInfo latest = |
- | // optionally print the output | + | directoryInfo.Files |
- | WScript.Echo(output); | + | ························.Where(file => !file.IsDirectory) |
+ | ························.OrderByDescending(file => file.LastWriteTime) | ||
+ | ························.FirstOrDefault(); | ||
- | if (exec.ExitCode != 0) | + | // Any file at all? |
- | { | + | ················if (latest == null) |
- | ···WScript.Echo("Error retrieving list of files"); | + | ················{ |
- | WScript.Quit(1); | + | ···················throw new Exception("No file found"); |
- | } | + | ···············} |
- | // look for log file | + | ················// Download the selected file |
- | var logfile = filesys.GetFile(logfilepath); | + | session.GetFileToDirectory(latest.FullName, localPath); |
+ | } | ||
- | if (logfile == null) | + | ············return 0; |
- | { | + | } |
- | WScript.Echo("Cannot find log file"); | + | catch (Exception e) |
- | 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; | + | Console.WriteLine("Error: {0}", e); |
- | ···········filenameLatest = filename.value; | + | return 1; |
} | } | ||
} | } | ||
} | } | ||
+ | </code> | ||
- | // no file in the log | + | ==== [[vbnet]] VB.NET ==== |
- | if (filenameLatest == null) | + | |
- | { | + | |
- | WScript.Echo("No file found"); | + | |
- | WScript.Quit(0); | + | |
- | } | + | |
- | // run winscp to download the latest file | + | The following snippet selects the most recent file from a directory listing. Most of the remaining code should be trivial to translate from the above C# example. |
- | 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 | + | <code vbnet> |
- | var output = exec.StdOut.ReadAll(); | + | Dim latest As RemoteFileInfo = |
- | // optionally print the output | + | directoryInfo.Files _ |
- | WScript.Echo(output); | + | ········.Where(Function(file) Not file.IsDirectory) _ |
+ | ········.OrderByDescending(Function(file) file.LastWriteTime) _ | ||
+ | ········.FirstOrDefault() | ||
+ | </code> | ||
- | if (exec.ExitCode != 0) | + | ===== [[scripting]] Using WinSCP Scripting ===== |
- | { | + | Use the ''[[scriptcommand_get#latest|-latest]]'' switch of the ''[[scriptcommand_get|get]]'' command: |
- | ···WScript.Echo("Error downloading " + filenameLatest); | + | |
- | ····WScript.Quit(1); | + | |
- | } | + | |
- | </code> | + | |
- | Run the script with command: | + | <code winscp> |
- | <code batch> | + | get -latest /home/user/* c:\downloaded\ |
- | cscript /nologo example.js | + | |
</code> | </code> | ||
- | ===== Alternatives ===== | + | ===== [[alternatives]] Alternatives ===== |
Some of following alternatives can be easier to implement or actually even more appropriate for your specific task: | 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 ''[[scriptcommand_synchronize|synchronize local]]'' in scripting or ''[[library_session_synchronizedirectories|Session.SynchronizeDirectories(SynchronizationMode.Local, ...)]]'' in .NET assembly); | + | * Synchronizing a remote directory to a local directory (using ''[[scriptcommand_synchronize|synchronize local]]'' in scripting; or ''[[library_session_synchronizedirectories|Session.SynchronizeDirectories]]'' with ''mode'' parameter set to ''SynchronizationMode.Local'' in .NET assembly); |
* Downloading all files created in the last 24 hours (using [[file_mask|file mask]] ''*>=1D''; e.g. ''%%get -filemask="*>=1D" /home/user/*%%'', or an equivalent in .NET assembly). | * Downloading all files created in the last 24 hours (using [[file_mask|file mask]] ''*>=1D''; e.g. ''%%get -filemask="*>=1D" /home/user/*%%'', or an equivalent in .NET assembly). | ||
- | * Downloading all files created today (using ''[[scripting#timestamp|%TIMESTAMP%]]'' syntax to format [[file_mask|file mask]] with today's time constraint, e.g. ''%%get -filemask="*>=%TIMESTAMP#yyyy-mm-dd%" /home/user/*%%'', or an equivalent in .NET assembly). | + | * Downloading all files created today (using the [[file_mask#today|''today'' keyword in the file mask]]; e.g. ''%%get -filemask="*>=today" /home/user/*%%'', or an equivalent in .NET assembly). |
+ | * If you need to download all files that were not downloaded yet, but you do not keep local copies of the files to synchronize the remote directory against, see [[library_example_remember_downloaded_files|*]]. | ||
===== Further Reading ===== | ===== Further Reading ===== | ||
Line 194: | Line 162: | ||
* Guide to [[guide_automation|scripting/automation]]; | * Guide to [[guide_automation|scripting/automation]]; | ||
* [[library|WinSCP .NET assembly]]; | * [[library|WinSCP .NET assembly]]; | ||
- | * [[library_powershell|Using WinSCP .NET Assembly from PowerShell]]. | + | * [[library_powershell|*]]. |