Differences
This shows you the differences between the selected revisions of the page.
| 2014-06-12 | 2014-06-17 | ||
| using Add-Type cmdlet instead of Assembly.LoadFrom method (martin) | no summary (122.181.146.2) (hidden) | ||
| Line 462: | Line 462: | ||
| Alternatively you can continue with the processing directly in JavaScript code as suggested by respective comments. | Alternatively you can continue with the processing directly in JavaScript code as suggested by respective comments. | ||
| + | |||
| + | ===== [[local_move_after_successful_upload]] Moving local files to different location after successful upload ===== | ||
| + | |||
| + | |||
| + | ==== [[library]] Using WinSCP .NET Assembly ==== | ||
| + | Use [[library|WinSCP .NET assembly]] from your favourite language. | ||
| + | |||
| + | If you do not have your favourite language, use [[library_powershell|PowerShell]]: | ||
| + | |||
| + | <code 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:\upload\*" | ||
| + | $remotePath = "/home/user/" | ||
| + | $backupPath = "C:\backup\" | ||
| + | |||
| + | # 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 | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | ==== Using WinSCP Scripting ==== | ||
| + | WinSCP scripting does not support move command for local files. Instead you can combine WinSCP script with batch file: | ||
| + | |||
| + | <code winscp> | ||
| + | option batch abort | ||
| + | option confirm off | ||
| + | # Connect | ||
| + | open mysession | ||
| + | # Upload the files | ||
| + | put *.* | ||
| + | </code> | ||
| + | |||
| + | Launch the above script from batch file like the one below: | ||
| + | |||
| + | <code> | ||
| + | winscp.com /script=example.txt | ||
| + | if ERRORLEVEL 1 goto error | ||
| + | |||
| + | echo Upload succeeded, moving local files | ||
| + | move *.* c:\backup\ | ||
| + | exit | ||
| + | |||
| + | :error | ||
| + | echo Upload failed, keeping local files | ||
| + | </code> | ||
| + | |||
| + | ===== [[synchronize_any_local_file]] 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''. &winpath | ||
| + | |||
| + | 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): | ||
| + | <code> | ||
| + | winscp.com /script=example.txt /parameter %1 "/home/user/www/%~n1%~x1" | ||
| + | </code> | ||
| + | |||
| + | The script ''example.txt'' may look like: | ||
| + | |||
| + | <code winscp> | ||
| + | # Being intended for interactive session, we are not enabling batch mode | ||
| + | # Connect | ||
| + | open mysession | ||
| + | # Synchronize paths provided via environment variables | ||
| + | synchronize remote "%1%" "%2%" | ||
| + | </code> | ||
| + | |||
| + | 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. &winpath | ||
| + | |||
| + | ===== [[auto_compress_download]] Automatically compress files before download ===== | ||
| + | Following script compresses selected files into tar/gzip archive and downloads it: | ||
| + | |||
| + | <code winscp> | ||
| + | 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 | ||
| + | </code> | ||
| + | |||
| + | Launch the above script from batch file like the one below, which automatically decompresses the archive: | ||
| + | |||
| + | <code> | ||
| + | winscp.com /script=example.txt /parameter %* | ||
| + | if errorlevel 1 goto error | ||
| + | |||
| + | echo Retrieving files succeeded | ||
| + | gzip -d archive.tar.gz | ||
| + | tar -xf archive.tar | ||
| + | del archive.tar | ||
| + | exit | ||
| + | |||
| + | :error | ||
| + | echo Retrieving files failed | ||
| + | </code> | ||
| + | |||
| + | Example of running the batch file to download all files under ''/home/user/www'': | ||
| + | |||
| + | <code> | ||
| + | example.bat /home/user/www *.* | ||
| + | </code> | ||
| + | |||
| + | The batch file needs Windows ports of ''gzip'' and ''tar'' tools. You can get them from [[http://sourceforge.net/projects/unxutils/|UnxUtils]] project. | ||
| + | |||
| + | ===== [[vbnet_robust_example]] Running WinSCP from VB.NET ===== | ||
| + | &deprecated_use_net | ||
| + | |||
| + | Following is more robust alternative to simple example contained in guide to [[guide_dotnet|SFTP file transfers in .NET]]. | ||
| + | |||
| + | <code vbnet> | ||
| + | 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 | ||
| + | </code> | ||
| + | |||
| + | <trailer> | ||
| + | ===== Further Reading ===== | ||
| + | |||
| + | |||
| + | |||
| + | * Guide to [[guide_automation|scripting/automation]]; | ||
| + | * [[library|WinSCP .NET assembly]]; | ||
| + | * [[library_powershell|Using WinSCP .NET Assembly from PowerShell]]. | ||
| + | </trailer> | ||
| + | |||
| + | <nosplit> | ||
| + | ===== Other Examples ===== | ||
| + | * Guide to [[guide_automation|scripting/automation]]; | ||
| + | * Guide to [[guide_automation_advanced|advanced scripting]]; | ||
| + | * See [[library_examples|WinSCP .NET assembly examples]] for advanced tasks. | ||
| + | </nosplit> | ||
| ===== [[local_move_after_successful_upload]] Moving local files to different location after successful upload ===== | ===== [[local_move_after_successful_upload]] Moving local files to different location after successful upload ===== | ||