Differences
This shows you the differences between the selected revisions of the page.
library_session_synchronizedirectories 2012-01-11 | library_session_synchronizedirectories 2024-02-15 (current) | ||
Line 1: | Line 1: | ||
====== Session.SynchronizeDirectories Method ====== | ====== Session.SynchronizeDirectories Method ====== | ||
- | [[task_synchronize_full|Synchronizes directories]]. | + | [[task_synchronize_full|Synchronizes]] content of a local directory with a remote one or vice versa or mutually. |
- | + | ||
- | &future_feature | + | |
===== Syntax ===== | ===== Syntax ===== | ||
- | <code csharp> | + | <code csharp *> |
public SynchronizationResult SynchronizeDirectories( | public SynchronizationResult SynchronizeDirectories( | ||
SynchronizationMode mode, | SynchronizationMode mode, | ||
Line 17: | Line 15: | ||
</code> | </code> | ||
- | ==== Parameters ==== | + | <code vbnet *> |
+ | Public Function SynchronizeDirectories( | ||
+ | mode As SynchronizationMode, | ||
+ | localPath As String, | ||
+ | remotePath As String, | ||
+ | removeFiles As Boolean, | ||
+ | Optional mirror As Boolean = False, | ||
+ | Optional criteria As SynchronizationCriteria = SynchronizationCriteria.Time, | ||
+ | Optional options As TransferOptions = Nothing | ||
+ | ) As SynchronizationResult | ||
+ | </code> | ||
+ | |||
+ | ==== [[parameters]] Parameters ==== | ||
^ Name ^ Description ^ | ^ Name ^ Description ^ | ||
- | | SynchronizationMode mode | [[task_synchronize_full#synchronization_mode|Synchronization mode]]. Possible values are ''SynchronizationMode.Local'', ''SynchronizationMode.Remote'' and ''SynchronizationMode.Both''. | | + | | SynchronizationMode ==mode== | [[task_synchronize_full##direction|Synchronization direction]]. Possible values are ''SynchronizationMode.Local'', ''SynchronizationMode.Remote'' and ''SynchronizationMode.Both''. | |
- | | string localPath | Full path to local directory. | | + | | string ==localPath== | Full path to local directory. | |
- | | string remotePath | Full path to remote directory. | | + | | string ==remotePath== | Full path to remote directory. | |
- | | bool removeFiles | When set to ''true'', deletes obsolete files. Cannot be used for ''SynchronizationMode.Both''. | | + | | bool ==removeFiles== | When set to ''true'', deletes obsolete files. Cannot be used for ''SynchronizationMode.Both''. | |
- | | bool mirror | When set to ''true'', synchronizes in [[task_synchronize_full#synchronization_mode|mirror mode]] (synchronizes also older files). Cannot be used for ''SynchronizationMode.Both''. Defaults to ''false''. | | + | | bool ==mirror== | When set to ''true'', synchronizes in [[task_synchronize_full#mode|mirror mode]] (synchronizes also older files). Cannot be used for ''SynchronizationMode.Both''. Defaults to ''false''. | |
- | | SynchronizationCriteria criteria | [[ui_synchronize#comparison_criteria|Comparison criteria]]. Possible values are ''SynchronizationCriteria.None'', ''SynchronizationCriteria.Time'' (default), ''SynchronizationCriteria.Size'' and ''SynchronizationCriteria.Either''. For ''SynchronizationMode.Both'' ''SynchronizationCriteria.Time'' can be used only. | | + | | SynchronizationCriteria ==criteria== | [[ui_synchronize#criteria|Comparison criteria]]. The parameter is a bit field of any of ''SynchronizationCriteria.Time'' (default), ''SynchronizationCriteria.Size'' and ''SynchronizationCriteria.Checksum''. ''SynchronizationCriteria.None'' can be used as an alias to empty bit field. For backward compatibility, ''SynchronizationCriteria.Either'' can be used as an alias to ''Time %%|%% Size''. For ''SynchronizationMode.Both'', ''SynchronizationCriteria.Time'' can be used only. | |
- | | [[library_transferoptions|TransferOptions]] options | Transfer options. Defaults to ''null'', what is equivalent to ''new TransferOptions()''. | | + | | [[library_transferoptions|TransferOptions]] ==options== | Transfer options. Defaults to ''null'', what is equivalent to ''new TransferOptions()''. | |
==== Return Value ==== | ==== Return Value ==== | ||
Line 37: | Line 47: | ||
| TimeoutException | Timeout waiting for ''winscp.com'' to respond. | | | TimeoutException | Timeout waiting for ''winscp.com'' to respond. | | ||
- | ===== Remarks ===== | + | ===== [[remarks]] Remarks ===== |
Event ''[[library_session_filetransferred|Session.FileTransferred]]'' is raised for every uploaded or downloaded file. | Event ''[[library_session_filetransferred|Session.FileTransferred]]'' is raised for every uploaded or downloaded file. | ||
- | ===== Example ===== | + | To further customize the synchronization, use instead a combination of [[library_session_comparedirectories|''Session.CompareDirectories'']] and [[library_comparisondifference_resolve|''ComparisonDifference.Resolve'']]. This allows synchronizing only selected differences, changing synchronization order or customizing error handling. |
+ | |||
+ | ===== [[example]] Examples ===== | ||
+ | |||
+ | ==== [[csharp]] C# Example ==== | ||
<code csharp> | <code csharp> | ||
using System; | using System; | ||
using WinSCP; | using WinSCP; | ||
- | class Test | + | class Example |
{ | { | ||
- | static void Main() | + | public static int Main() |
{ | { | ||
try | try | ||
{ | { | ||
// Setup session options | // Setup session options | ||
- | SessionOptions sessionOptions = new SessionOptions(); | + | SessionOptions sessionOptions = new SessionOptions |
- | sessionOptions.Protocol = Protocol.Sftp; | + | { |
- | sessionOptions.HostName = "example.com"; | + | ················Protocol = Protocol.Sftp, |
- | sessionOptions.UserName = "user"; | + | ···············HostName = "example.com", |
- | sessionOptions.Password = "mypassword"; | + | ···············UserName = "user", |
- | sessionOptions.SshHostKey = "ssh-rsa 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"; | + | ···············Password = "mypassword", |
+ | ···············SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." | ||
+ | }; | ||
using (Session session = new Session()) | using (Session session = new Session()) | ||
Line 67: | Line 83: | ||
session.Open(sessionOptions); | session.Open(sessionOptions); | ||
+ | // Synchronize files | ||
SynchronizationResult synchronizationResult; | SynchronizationResult synchronizationResult; | ||
synchronizationResult = | synchronizationResult = | ||
session.SynchronizeDirectories( | session.SynchronizeDirectories( | ||
- | SynchronizationMode.Remote, @"d:\www", "/home/martin/public_html", false); | + | SynchronizationMode.Remote, @"d:\www", |
+ | ·······················"/home/martin/public_html", false); | ||
// Throw on any error | // Throw on any error | ||
synchronizationResult.Check(); | synchronizationResult.Check(); | ||
} | } | ||
+ | |||
+ | return 0; | ||
} | } | ||
catch (Exception e) | catch (Exception e) | ||
{ | { | ||
Console.WriteLine("Error: {0}", e); | Console.WriteLine("Error: {0}", e); | ||
+ | return 1; | ||
} | } | ||
} | } | ||
Line 97: | Line 118: | ||
if (e.Chmod.Error == null) | if (e.Chmod.Error == null) | ||
{ | { | ||
- | Console.WriteLine("Permisions of {0} set to {1}", e.Chmod.FileName, e.Chmod.FilePermissions); | + | Console.WriteLine( |
+ | ····················"Permissions of {0} set to {1}", e.Chmod.FileName, e.Chmod.FilePermissions); | ||
} | } | ||
else | else | ||
{ | { | ||
- | Console.WriteLine("Setting permissions of {0} failed: {1}", e.Chmod.FileName, e.Chmod.Error); | + | Console.WriteLine( |
+ | ····················"Setting permissions of {0} failed: {1}", e.Chmod.FileName, e.Chmod.Error); | ||
} | } | ||
} | } | ||
Line 113: | Line 136: | ||
if (e.Touch.Error == null) | if (e.Touch.Error == null) | ||
{ | { | ||
- | Console.WriteLine("Timestamp of {0} set to {1}", e.Touch.FileName, e.Touch.LastWriteTime); | + | Console.WriteLine( |
+ | ····················"Timestamp of {0} set to {1}", e.Touch.FileName, e.Touch.LastWriteTime); | ||
} | } | ||
else | else | ||
{ | { | ||
- | Console.WriteLine("Setting timestamp of {0} failed: {1}", e.Touch.FileName, e.Touch.Error); | + | Console.WriteLine( |
+ | ····················"Setting timestamp of {0} failed: {1}", e.Touch.FileName, e.Touch.Error); | ||
} | } | ||
} | } | ||
else | else | ||
{ | { | ||
- | // This should never happen with Session.SynchronizeDirectories | + | // This should never happen during "local to remote" synchronization |
- | Console.WriteLine("Timestamp of {0} kept with its default (current time)", e.Destination); | + | Console.WriteLine( |
+ | ················"Timestamp of {0} kept with its default (current time)", e.Destination); | ||
} | } | ||
} | } | ||
} | } | ||
</code> | </code> | ||
+ | |||
+ | ==== [[vbnet]] VB.NET Example ==== | ||
+ | <code vbnet> | ||
+ | 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 | ||
+ | ' Will continuously report progress of synchronization | ||
+ | AddHandler session.FileTransferred, AddressOf FileTransferred | ||
+ | |||
+ | ' Connect | ||
+ | session.Open(sessionOptions) | ||
+ | |||
+ | ' Synchronize files | ||
+ | Dim synchronizationResult As SynchronizationResult | ||
+ | synchronizationResult = | ||
+ | session.SynchronizeDirectories( | ||
+ | SynchronizationMode.Remote, "d:\www", "/home/martin/public_html", False) | ||
+ | |||
+ | ' Throw on any error | ||
+ | synchronizationResult.Check() | ||
+ | End Using | ||
+ | |||
+ | Return 0 | ||
+ | Catch e As Exception | ||
+ | Console.WriteLine("Error: {0}", e) | ||
+ | Return 1 | ||
+ | End Try | ||
+ | |||
+ | End Function | ||
+ | |||
+ | Private Shared Sub FileTransferred(sender As Object, e As TransferEventArgs) | ||
+ | |||
+ | If e.Error Is Nothing Then | ||
+ | Console.WriteLine("Upload of {0} succeeded", e.FileName) | ||
+ | Else | ||
+ | Console.WriteLine("Upload of {0} failed: {1}", e.FileName, e.Error) | ||
+ | End If | ||
+ | |||
+ | If e.Chmod IsNot Nothing Then | ||
+ | If e.Chmod.Error Is Nothing Then | ||
+ | Console.WriteLine( | ||
+ | "Permissions of {0} set to {1}", e.Chmod.FileName, e.Chmod.FilePermissions) | ||
+ | Else | ||
+ | Console.WriteLine( | ||
+ | "Setting permissions of {0} failed: {1}", e.Chmod.FileName, e.Chmod.Error) | ||
+ | End If | ||
+ | Else | ||
+ | Console.WriteLine("Permissions of {0} kept with their defaults", e.Destination) | ||
+ | End If | ||
+ | |||
+ | If e.Touch IsNot Nothing Then | ||
+ | If e.Touch.Error Is Nothing Then | ||
+ | Console.WriteLine( | ||
+ | "Timestamp of {0} set to {1}", e.Touch.FileName, e.Touch.LastWriteTime) | ||
+ | Else | ||
+ | Console.WriteLine( | ||
+ | "Setting timestamp of {0} failed: {1}", e.Touch.FileName, e.Touch.Error) | ||
+ | End If | ||
+ | Else | ||
+ | ' This should never happen during "local to remote" synchronization | ||
+ | Console.WriteLine( | ||
+ | "Timestamp of {0} kept with its default (current time)", e.Destination) | ||
+ | End If | ||
+ | |||
+ | End Sub | ||
+ | |||
+ | End Class | ||
+ | </code> | ||
+ | |||
+ | ==== [[powershell]] PowerShell Example ==== | ||
+ | Learn more about [[library_powershell|using WinSCP .NET assembly from PowerShell]]. | ||
+ | |||
+ | <code powershell> | ||
+ | # Load WinSCP .NET assembly | ||
+ | Add-Type -Path "WinSCPnet.dll" | ||
+ | |||
+ | # Session.FileTransferred event handler | ||
+ | |||
+ | function FileTransferred | ||
+ | { | ||
+ | param($e) | ||
+ | |||
+ | if ($e.Error -eq $Null) | ||
+ | { | ||
+ | Write-Host "Upload of $($e.FileName) succeeded" | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Write-Host "Upload of $($e.FileName) failed: $($e.Error)" | ||
+ | } | ||
+ | |||
+ | if ($e.Chmod -ne $Null) | ||
+ | { | ||
+ | if ($e.Chmod.Error -eq $Null) | ||
+ | { | ||
+ | Write-Host "Permissions of $($e.Chmod.FileName) set to $($e.Chmod.FilePermissions)" | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Write-Host "Setting permissions of $($e.Chmod.FileName) failed: $($e.Chmod.Error)" | ||
+ | } | ||
+ | |||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Write-Host "Permissions of $($e.Destination) kept with their defaults" | ||
+ | } | ||
+ | |||
+ | if ($e.Touch -ne $Null) | ||
+ | { | ||
+ | if ($e.Touch.Error -eq $Null) | ||
+ | { | ||
+ | Write-Host "Timestamp of $($e.Touch.FileName) set to $($e.Touch.LastWriteTime)" | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Write-Host "Setting timestamp of $($e.Touch.FileName) failed: $($e.Touch.Error)" | ||
+ | } | ||
+ | |||
+ | } | ||
+ | else | ||
+ | { | ||
+ | # This should never happen during "local to remote" synchronization | ||
+ | Write-Host "Timestamp of $($e.Destination) kept with its default (current time)" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # Main script | ||
+ | |||
+ | try | ||
+ | { | ||
+ | $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 | ||
+ | { | ||
+ | # Will continuously report progress of synchronization | ||
+ | $session.add_FileTransferred( { FileTransferred($_) } ) | ||
+ | |||
+ | # Connect | ||
+ | $session.Open($sessionOptions) | ||
+ | |||
+ | # Synchronize files | ||
+ | $synchronizationResult = $session.SynchronizeDirectories( | ||
+ | [WinSCP.SynchronizationMode]::Remote, "d:\www", "/home/martin/public_html", $False) | ||
+ | |||
+ | # Throw on any error | ||
+ | $synchronizationResult.Check() | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | # Disconnect, clean up | ||
+ | $session.Dispose() | ||
+ | } | ||
+ | |||
+ | exit 0 | ||
+ | } | ||
+ | catch | ||
+ | { | ||
+ | Write-Host "Error: $($_.Exception.Message)" | ||
+ | exit 1 | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== [[jscript]] JScript (WSH) Example ==== | ||
+ | In this example the JScript script is embedded into WSF file, to allow [[library_com_wsh#enums|access to enumeration values]]. | ||
+ | |||
+ | <code javascript> | ||
+ | <job> | ||
+ | <reference object="WinSCP.Session" /> | ||
+ | <script language="JScript"> | ||
+ | |||
+ | // Session.FileTransferred event handler | ||
+ | |||
+ | function session_FileTransferred(sender, e) | ||
+ | { | ||
+ | if (e.Error == null) | ||
+ | { | ||
+ | WScript.Echo("Upload of " + e.FileName + " succeeded"); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | WScript.Echo("Upload of " + e.FileName + " failed: " + e.Error); | ||
+ | } | ||
+ | |||
+ | if (e.Chmod != null) | ||
+ | { | ||
+ | if (e.Chmod.Error == null) | ||
+ | { | ||
+ | WScript.Echo( | ||
+ | "Permissions of " + e.Chmod.FileName + " set to " + e.Chmod.FilePermissions); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | WScript.Echo( | ||
+ | "Setting permissions of " + e.Chmod.FileName + " failed: " + e.Chmod.Error); | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | WScript.Echo("Permissions of " + e.Destination + " kept with their defaults"); | ||
+ | } | ||
+ | |||
+ | if (e.Touch != null) | ||
+ | { | ||
+ | if (e.Touch.Error == null) | ||
+ | { | ||
+ | WScript.Echo( | ||
+ | "Timestamp of " + e.Touch.FileName + " set to " + e.Touch.LastWriteTime); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | WScript.Echo( | ||
+ | "Setting timestamp of " + e.Touch.FileName + " failed: " + e.Touch.Error); | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // This should never happen during "local to remote" synchronization | ||
+ | WScript.Echo( | ||
+ | "Timestamp of " + e.Destination + " kept with its default (current time)"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Main script | ||
+ | |||
+ | 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", "session_"); | ||
+ | |||
+ | try | ||
+ | { | ||
+ | // Connect | ||
+ | session.Open(sessionOptions); | ||
+ | |||
+ | // Synchronize files | ||
+ | var synchronizationResult = session.SynchronizeDirectories( | ||
+ | SynchronizationMode_Remote, "D:\\www", "/home/martin/public_html", false); | ||
+ | |||
+ | // Throw on any error | ||
+ | synchronizationResult.Check(); | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | // Disconnect, clean up | ||
+ | session.Dispose(); | ||
+ | } | ||
+ | } | ||
+ | catch (e) | ||
+ | { | ||
+ | WScript.Echo("Error: " + e.message); | ||
+ | WScript.Quit(1); | ||
+ | } | ||
+ | |||
+ | </script> | ||
+ | </job> | ||
+ | </code> | ||
+ | |||
+ | ==== [[reallife]] Real-Life Example ==== | ||
+ | |||
+ | * [[library_example_delete_after_successful_download|*]]. | ||