.NET Assemblies session.SynchronizeDirectories events
Dear all,
I recently tried to implement SynchronizeDirectories to a new wpf app I'm building and I'm facing weird issues with events that are acting in a strange way.
The synchronization is working properly in both ways, but the progressbar is not updated during the synchronization itself, only at the end of the process. In short terms, my code is going to eventHandlers but not updating the window itself. Any ideas on that ?
Here is the code I'm using :
ProgressWindow.xaml
ProgressWindow.xaml.cs
Thanks in advance for any hints.
Regards,
Caz
I recently tried to implement SynchronizeDirectories to a new wpf app I'm building and I'm facing weird issues with events that are acting in a strange way.
The synchronization is working properly in both ways, but the progressbar is not updated during the synchronization itself, only at the end of the process. In short terms, my code is going to eventHandlers but not updating the window itself. Any ideas on that ?
Here is the code I'm using :
ProgressWindow.xaml
<Window x:Class="MyApp.SynchronizationWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="Mod synchronization" Width="500" WindowStyle="ToolWindow" SizeToContent="Height" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False" ContentRendered="Window_ContentRendered"> <DockPanel> <StackPanel DockPanel.Dock="Bottom"> <StatusBar> <StatusBarItem> <TextBlock Name="statusText" /> </StatusBarItem> </StatusBar> </StackPanel> <StackPanel Margin="0,0,0,5"> <Label Content="Current File" /> <Label Name="fileName" Content="" BorderThickness="0" Margin="30,0,10,0" /> <StackPanel Margin="50,0"> <StackPanel Orientation="Horizontal"> <Label Content="File progress :" /> <Label Name="filePercentage" Content="0%" /> </StackPanel> <ProgressBar Name="fileProgress" Height="15" Foreground="#FF01D328" /> <StackPanel Orientation="Horizontal"> <Label Content="Overall progress :" /> <Label Name="overallPercentage" Content="0%" /> </StackPanel> <ProgressBar Name="overallProgress" Height="15" Foreground="#FF0160D3" /> </StackPanel> </StackPanel> </DockPanel> </Window>
using MyApp; using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows; using WinSCP; using System.Linq; namespace MyApp { /// <summary> /// Interaction logic for SynchronizationWindow.xaml /// </summary> public partial class SynchronizationWindow : Window { private string _lastFileProcessed; private int _countFilesToSynchronize; private int _countFilesProcessed; private Action _selectedAction; public enum Action { DOWNLOAD, UPLOAD } public SynchronizationWindow(Action selectedAction) { InitializeComponent(); ResetComponents(); _selectedAction = selectedAction; } private void ResetComponents() { _countFilesToSynchronize = 0; _countFilesProcessed = 0; statusText.Text = null; fileName.Content = null; filePercentage.Content = "0%"; fileProgress.Value = 0; overallPercentage.Content = "0%"; overallProgress.Value = 0; } private void SynchronizeToRemote() { try { // Setup session options SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Sftp, HostName = Settings.Default.RepositoryUrl, UserName = Settings.Default.RepositoryName, Password = Settings.Default.RepositoryPassword, SshPrivateKeyPath = Settings.Default.RepositoryPrivateKeyPath, PrivateKeyPassphrase = Settings.Default.RepositoryPrivateKeyPassphrase, GiveUpSecurityAndAcceptAnySshHostKey = true }; using (Session session = new Session()) { // Will continuously report progress of synchronization session.FileTransferred += FileTransferred; // Will continuously report progress of transfer session.FileTransferProgress += SessionFileTransferProgress; // Connect session.Open(sessionOptions); string localPath = Path.Combine("C:\\test"); string remotePath = Path.Combine(Settings.Default.RepositoryStoragePath, "test"); if (!session.FileExists(remotePath)) { session.CreateDirectory(remotePath); } HashSet<string> filesToSynchronize = new HashSet<string>(Directory.GetFiles(localPath, "*.*", SearchOption.AllDirectories).ToList()); _countFilesToSynchronize = filesToSynchronize.Count; SynchronizationResult synchronizationResult; synchronizationResult = session.SynchronizeDirectories(SynchronizationMode.Remote, localPath, remotePath, true); // Throw on any error synchronizationResult.Check(); StringBuilder failedFiles = new StringBuilder(); foreach (TransferEventArgs failedFile in synchronizationResult.Failures) { failedFiles.AppendLine(string.Format("{0}", failedFile.FileName)); } if (failedFiles.Length > 0) { MessageBox.Show(failedFiles.ToString(), "Error uploading files."); } if (synchronizationResult.IsSuccess) { overallPercentage.Content = string.Format("{0:P0}", 1); overallProgress.Value = 100; statusText.Text = "Operation succeeded."; } } } catch (Exception ex) { Console.WriteLine("Error: {0}", ex); } } private void SynchronizeToLocal() { try { // Setup session options SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Sftp, HostName = Settings.Default.RepositoryUrl, UserName = Settings.Default.RepositoryName, Password = Settings.Default.RepositoryPassword, SshPrivateKeyPath = Settings.Default.RepositoryPrivateKeyPath, PrivateKeyPassphrase = Settings.Default.RepositoryPrivateKeyPassphrase, GiveUpSecurityAndAcceptAnySshHostKey = true }; using (Session session = new Session()) { // Will continuously report progress of synchronization session.FileTransferred += FileTransferred; // Will continuously report progress of transfer session.FileTransferProgress += SessionFileTransferProgress; // Connect session.Open(sessionOptions); string localPath = Path.Combine("C:\\test"); string remotePath = Path.Combine(Settings.Default.RepositoryStoragePath, "test"); if (!session.FileExists(remotePath)) { MessageBox.Show(string.Format("The mod [{0}] doesn't exist in the remote repository [{1}].", Mod.Name, Settings.Default.RepositoryStoragePath)); return; } if (!Directory.Exists(localPath)) { Directory.CreateDirectory(localPath); } RemoteDirectoryInfo remoteDirectoryInfo = session.ListDirectory(remotePath); _countFilesToSynchronize = remoteDirectoryInfo.Files.Count; SynchronizationResult synchronizationResult; synchronizationResult = session.SynchronizeDirectories(SynchronizationMode.Local, localPath, remotePath, true); // Throw on any error synchronizationResult.Check(); StringBuilder failedFiles = new StringBuilder(); foreach (TransferEventArgs failedFile in synchronizationResult.Failures) { failedFiles.AppendLine(string.Format("{0}", failedFile.FileName)); } if (failedFiles.Length > 0) { MessageBox.Show(failedFiles.ToString(), "Error downloading files."); } if (synchronizationResult.IsSuccess) { overallPercentage.Content = string.Format("{0:P0}", 1); overallProgress.Value = 100; statusText.Text = "Operation succeeded."; } } } catch (Exception ex) { Console.WriteLine("Error: {0}", ex); } } private void FileTransferred(object sender, TransferEventArgs e) { string returnMessage = string.Empty; if (e.Error == null) { returnMessage = $"Upload of {e.FileName} succeeded"; } else { returnMessage = $"Upload of {e.FileName} failed: {e.Error}"; } if (e.Chmod != null) { if (e.Chmod.Error == null) { returnMessage = $"Permissions of {e.Chmod.FileName} set to {e.Chmod.FilePermissions}"; } else { returnMessage = $"Setting permissions of {e.Chmod.FileName} failed: {e.Chmod.Error}"; } } else { returnMessage = $"Permissions of {e.Destination} kept with their defaults"; } if (e.Touch != null) { if (e.Touch.Error == null) { returnMessage = string.Format("Timestamp of {0} set to {1}", e.Touch.FileName, e.Touch.LastWriteTime); } else { returnMessage = string.Format("Setting timestamp of {0} failed: {1}", e.Touch.FileName, e.Touch.Error); } } else { // This should never happen during "local to remote" synchronization returnMessage = string.Format("Timestamp of {0} kept with its default (current time)", e.Destination); } Console.WriteLine(returnMessage); statusText.Text = returnMessage; UpdateOverallProgress(); } private void UpdateOverallProgress() { _countFilesProcessed++; double currentOverallPercentage = (double)_countFilesProcessed / _countFilesToSynchronize; overallPercentage.Content = string.Format("{0:P0}", currentOverallPercentage); overallProgress.Value = currentOverallPercentage * 100; } private void SessionFileTransferProgress(object sender, FileTransferProgressEventArgs e) { // New line for every new file if (_lastFileProcessed != null && _lastFileProcessed != e.FileName) { fileName.Content = String.Format("File [{0}] processed.", e.FileName); } // Print transfer progress string percentage = String.Format("{0:P1}", e.FileProgress); filePercentage.Content = percentage; fileProgress.Value = e.FileProgress * 100; // Remember a name of the last file reported _lastFileProcessed = e.FileName; } private void Window_ContentRendered(object sender, EventArgs e) { switch (_selectedAction) { case Action.DOWNLOAD: SynchronizeToLocal(); break; case Action.UPLOAD: SynchronizeToRemote(); break; } } } }
Thanks in advance for any hints.
Regards,
Caz