Imports System
Imports System.IO
Imports Microsoft.Synchronization
Imports Microsoft.Synchronization.Files
Namespace Microsoft.Samples.Synchronization
Class Program
' File synchronization provider requires applications to use the multithreaded apartment (MTA)
' threading model. This is specified by using the MTAThread attribute.
<MTAThreadAttribute()> _
Public Shared Sub Main(ByVal args As String())
If args.Length < 2 OrElse String.IsNullOrEmpty(args(0)) OrElse String.IsNullOrEmpty(args(1)) OrElse Not Directory.Exists(args(0)) OrElse Not Directory.Exists(args(1)) Then
Console.WriteLine("Usage: MyExecutableName.exe [valid directory path 1] [valid directory path 2]")
Exit Sub
End If
Dim replica1RootPath As String = args(0)
Dim replica2RootPath As String = args(1)
Try
' Set options for the synchronization session. In this case, options specify
' that the application will explicitly call FileSyncProvider.DetectChanges, and
' that items should be moved to the Recycle Bin instead of being permanently deleted.
Dim options As FileSyncOptions = _
FileSyncOptions.ExplicitDetectChanges Or FileSyncOptions.RecycleDeletedFiles _
Or FileSyncOptions.RecyclePreviousFileOnUpdates _
Or FileSyncOptions.RecycleConflictLoserFiles
' Create a filter that excludes all *.lnk files. The same filter should be used
' by both providers.
Dim filter As New FileSyncScopeFilter()
filter.FileNameExcludes.Add("*.lnk")
' Explicitly detect changes on both replicas before syncyhronization occurs.
' This avoids two change detection passes for the bidirectional synchronization
' that we will perform.
DetectChangesOnFileSystemReplica(replica1RootPath, filter, options)
DetectChangesOnFileSystemReplica(replica2RootPath, filter, options)
' Synchronize the replicas in both directions. In the first session replica 1 is
' the source, and in the second session replica 2 is the source. The third parameter
' (the filter value) is null because the filter is specified in DetectChangesOnFileSystemReplica().
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, Nothing, options)
SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, Nothing, options)
Catch e As Exception
Console.WriteLine(vbLf & "Exception from File Sync Provider:" & vbLf & e.ToString())
End Try
End Sub
' Create a provider, and detect changes on the replica that the provider
' represents.
Public Shared Sub DetectChangesOnFileSystemReplica(ByVal replicaRootPath As String, ByVal filter As FileSyncScopeFilter, _
ByVal options As FileSyncOptions)
Dim provider As FileSyncProvider = Nothing
Try
provider = New FileSyncProvider(replicaRootPath, filter, options)
provider.DetectChanges()
Finally
' Release resources.
If provider IsNot Nothing Then
provider.Dispose()
End If
End Try
End Sub
Public Shared Sub SyncFileSystemReplicasOneWay(ByVal sourceReplicaRootPath As String, _
ByVal destinationReplicaRootPath As String, ByVal filter As FileSyncScopeFilter, _
ByVal options As FileSyncOptions)
Dim sourceProvider As FileSyncProvider = Nothing
Dim destinationProvider As FileSyncProvider = Nothing
Try
' Instantiate source and destination providers, with a null filter (the filter
' was specified in DetectChangesOnFileSystemReplica()), and options for both.
sourceProvider = New FileSyncProvider(sourceReplicaRootPath, filter, options)
destinationProvider = New FileSyncProvider(destinationReplicaRootPath, filter, options)
' Register event handlers so that we can write information
' to the console.
AddHandler destinationProvider.AppliedChange, AddressOf OnAppliedChange
AddHandler destinationProvider.SkippedChange, AddressOf OnSkippedChange
' Use SyncCallbacks for conflicting items.
Dim destinationCallbacks As SyncCallbacks = destinationProvider.DestinationCallbacks
AddHandler destinationCallbacks.ItemConflicting, AddressOf OnItemConflicting
AddHandler destinationCallbacks.ItemConstraint, AddressOf OnItemConstraint
Dim agent As New SyncOrchestrator()
agent.LocalProvider = sourceProvider
agent.RemoteProvider = destinationProvider
agent.Direction = SyncDirectionOrder.Upload
' Upload changes from the source to the destination.
Console.WriteLine("Synchronizing changes to replica: " & destinationProvider.RootDirectoryPath)
agent.Synchronize()
Finally
' Release resources.
If sourceProvider IsNot Nothing Then
sourceProvider.Dispose()
End If
If destinationProvider IsNot Nothing Then
destinationProvider.Dispose()
End If
End Try
End Sub
' Provide information about files that were affected by the synchronization session.
Public Shared Sub OnAppliedChange(ByVal sender As Object, ByVal args As AppliedChangeEventArgs)
Select Case args.ChangeType
Case ChangeType.Create
Console.WriteLine("-- Applied CREATE for file " & args.NewFilePath)
Exit Select
Case ChangeType.Delete
Console.WriteLine("-- Applied DELETE for file " & args.OldFilePath)
Exit Select
Case ChangeType.Update
Console.WriteLine("-- Applied OVERWRITE for file " & args.OldFilePath)
Exit Select
Case ChangeType.Rename
Console.WriteLine(("-- Applied RENAME for file " & args.OldFilePath & " as ") & args.NewFilePath)
Exit Select
End Select
End Sub
' Provide error information for any changes that were skipped.
Public Shared Sub OnSkippedChange(ByVal sender As Object, ByVal args As SkippedChangeEventArgs)
Console.WriteLine(("-- Skipped applying " & args.ChangeType.ToString().ToUpper() & " for ") & (If(Not String.IsNullOrEmpty(args.CurrentFilePath), args.CurrentFilePath, args.NewFilePath)) & " due to error")
If args.Exception IsNot Nothing Then
Console.WriteLine(" [" & args.Exception.Message & "]")
End If
End Sub
' By default, conflicts are resolved in favor of the last writer. In this example,
' the change from the source in the first session (replica 1), will always
' win the conflict.
Public Shared Sub OnItemConflicting(ByVal sender As Object, ByVal args As ItemConflictingEventArgs)
args.SetResolutionAction(ConflictResolutionAction.SourceWins)
Console.WriteLine("-- Concurrency conflict detected for item " & args.DestinationChange.ItemId.ToString())
End Sub
Public Shared Sub OnItemConstraint(ByVal sender As Object, ByVal args As ItemConstraintEventArgs)
args.SetResolutionAction(ConstraintConflictResolutionAction.SourceWins)
Console.WriteLine("-- Constraint conflict detected for item " & args.DestinationChange.ItemId.ToString())
End Sub
End Class
End Namespace