Synchronize then delete using WinSCP on C#


10.17.15 Posted in Technology by

Objective

To automate synchronization on C# using .NET assembly method Session.SynchronizeDirectories.

Requirement

  1. Visual Studio IDE
  2. Download and Install WinSCP .NET assembly. See installation instructions.
  3. To use WinSCP DLL method, add the DLL(WinSCPnet.dll) via the solution explorer – right click on references –> add reference then “Browse” to you DLL – then it should be available.
  4. Create a configuration file for the app(e.g. App.config)

Let’s Get Started

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <appSettings>
    <add key="HostName" value="example.com" />
    <add key="FtpUser" value="xxxx" />
    <add key="FtpPassword" value="yyyy" />
    <add key="SshKey" value="ssh-rsa xxxx aa:bb:cc:dd:ee:ff:gg:hh:ii:jj:kk:ll:mm:nn:oo:pp" />
    <add key="LocalDirectoryPath" value="C:\Local\Directory\Path" />
    <add key="RemoteDirectoryPath" value="/remote/directory/path" />
  </appSettings>
</configuration>

The following example uses WinSCP .NET assembly from a C# script.

using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Configuration;
using System.IO;
using WinSCP;

namespace Sync
{
    class Program
    {
        
        public static void Main()
        {
            
            try
            {
                
                
                SessionOptions sessionOptions = new SessionOptions
                {
                    Protocol = Protocol.Sftp,
                    //access settings from configuration file App.config
                    HostName = ConfigurationManager.AppSettings["HostName"], 
                    UserName = ConfigurationManager.AppSettings["FtpUser"],
                    Password = ConfigurationManager.AppSettings["FtpPassword"],
                    SshHostKeyFingerprint = ConfigurationManager.AppSettings["SshKey"]
                };
                Session session = new Session();
                session.Open(sessionOptions); //open a session and connect to FTP server
                try
                    {
                       
                        //call to upload files from local directory then delete them right after
                        SynchronizationResult synchronizationResultUp;
                        //Synchronize files to remote directory, collect results
                        synchronizationResultUp = session.SynchronizeDirectories(SynchronizationMode.Remote, @"" 
+ ConfigurationManager.AppSettings["LocalDirectoryPath"] + "", ConfigurationManager.AppSettings["RemoteDirectoryPath"], false);
                        
                        //call to download files from remote directory then delete them right after
                        SynchronizationResult synchronizationResultDown;
                        //Synchronize files to local directory, collect results
                        synchronizationResultDown = session.SynchronizeDirectories(SynchronizationMode.Local, @"" 
+ ConfigurationManager.AppSettings["LocalDirectoryPath"] + "", ConfigurationManager.AppSettings["RemoteDirectoryPath"], false);

                        DownloadAndRemove(synchronizationResultDown, session);
                        UploadAndRemove(synchronizationResultUp);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(DateTime.Now + ": Error: {0}", e);
                        session.Dispose(); //Disconnect, clean up

                    }
               
            }
            catch (Exception er)
            {

                Console.WriteLine(DateTime.Now + ": Error: {0}", er);

            }

        }

        //upload files from local directory then delete them right after
        static void UploadAndRemove(SynchronizationResult synchronizationResultUp) 
        {
            // Iterate over every upload
            foreach (TransferEventArgs e in synchronizationResultUp.Uploads)
            {
                Console.WriteLine(DateTime.Now + ": Upload of {0} succeeded, removing from source", e.FileName);
                if (e.Error == null)
                {
                    Console.WriteLine(DateTime.Now + ": Upload of {0} succeeded, removing from source", e.FileName);

                    if (File.Exists(@"" + e.FileName + ""))
                    {
                        File.Delete(@"" + e.FileName + "");
                        if (!(File.Exists(@"" + e.FileName + "")))
                        {
                            Console.WriteLine(DateTime.Now + ": Removing of file {0} succeeded ", e.FileName);
                        }
                        else
                        {
                            Console.WriteLine(DateTime.Now + ": Removing of file {0} failed", e.FileName);
                        }

                    }


                }
                else
                {
                    Console.WriteLine(DateTime.Now + ": Upload of {0} failed: {1}", e.Chmod.FileName, e.Chmod.Error);
                }
            }
        }
        
        //download files from remote directory then delete them right after
        static void DownloadAndRemove(SynchronizationResult synchronizationResultDown, Session session)
        {
            // Iterate over every download
            foreach (TransferEventArgs e in synchronizationResultDown.Downloads)
            {
                Console.WriteLine(DateTime.Now + ": Download of {0} succeeded, removing from source", e.FileName);
                if (e.Error == null)
                {
                    Console.WriteLine(DateTime.Now + ": Download of {0} succeeded, removing from source", e.FileName);

                    var removalResult = session.RemoveFiles(session.EscapeFileMask(e.FileName));

                    if (removalResult.IsSuccess)
                    {
                        Console.WriteLine(DateTime.Now + ": Removing of file {0} succeeded ", e.FileName);
                    }
                    else
                    {
                        Console.WriteLine(DateTime.Now + ": Removing of file {0} failed", e.FileName);
                    }
                }
                else
                {
                    Console.WriteLine(DateTime.Now + ": Download of {0} failed: {1}", e.Chmod.FileName, e.Chmod.Error);
                }
            }
        }
    }
}

Conclusion

This C# app can be run at every interval to check for files to upload and download. I utilised System.Threading for the application to continuously check for files in a loop and let it sleep at intervals.
For more examples in other language, check out WinSCP .NET assembly examples.



Comments are closed.