Click here to Skip to main content
15,889,034 members
Articles / Desktop Programming / Windows Forms
Article

Backup Utility

Rate me:
Please Sign up or sign in to vote.
4.11/5 (13 votes)
20 Nov 2008CPOL1 min read 47.1K   2.4K   56   6
A simple OO backup utility that preserves full file paths
main.PNG

Introduction

This little utility was developed for work so that deployment locations (DEV, QA, PROD) could be backed up before running a new deployment.  It has served its purpose well and saved my butt and my co-worker's butts a number of times. Here are a few highlights:

  • OO Design
  • UI Threaded
  • Able to back up files in network locations 
  • Uses XML backup sets
  • Preserves full file locations

options_general.PNG

Backup set options. Set name, description, and where the backup files will be dropped.

options_directories.PNG

Backup set options. Add directories to be backed up here. Directories need to be typed in or copied and pasted because of the limitation of the built-in file browser which does not allow adding network locations.

The Serializable BackupSetInfo Type

C#
[Serializable]
public class BackupSetInfo
{
  private string BackupDescriptionField;

  private string BackupNameField;

  private List<string> BackupDirectoriesField;

  private string BackupToDirectoryField;

  public string BackupDescription
  {
    get { return BackupDescriptionField; }
    set { BackupDescriptionField = value; }
  }

  public string BackupName
  {
    get { return BackupNameField; }
    set { BackupNameField = value; }
  }

  public List<string> BackupDirectories
  {
    get { return BackupDirectoriesField; }
    set { BackupDirectoriesField = value; }
  }

  public string BackupToDirectory
  {
    get { return BackupToDirectoryField; }
    set { BackupToDirectoryField = value; }
  }

  public BackupSetInfo()
  {
    this.BackupDirectories = new List<string>();
  }
}

Backup sets are saved by serializing the object instance to the file system.

C#
public void Update(BackupSetInfo BackupSetInfoOf)
{
  bool isUpdate = false;
  for (int i = 0; i < this.ListOfBackupSetInfo.Count; i++)
  {
    if (this.ListOfBackupSetInfo[i].BackupName == BackupSetInfoOf.BackupName)
    {
      this.ListOfBackupSetInfo[i] = BackupSetInfoOf;
      isUpdate = true;
    }
  }
  if (!isUpdate)
    this.ListOfBackupSetInfo.Add(BackupSetInfoOf);

  SerializeXml(BackupSetInfoOf.BackupName.Replace(" ", "") + ".backupset", 
		typeof(BackupSetInfo), BackupSetInfoOf);
}

private void SerializeXml(string FileName, Type ObjectType, object InstanceToSerialize)
{
  File.Delete(FileName);
  using (FileStream fs = new FileStream
	(AppDomain.CurrentDomain.BaseDirectory + FileName, FileMode.Create))
  {
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs))
    {
      XmlSerializer serializer = new XmlSerializer(ObjectType);
      serializer.Serialize(writer, InstanceToSerialize);
    }
  }
}

Backup sets are deserialized and objects are loaded as part of the ListOfBackupSetInfo.

C#
public void LoadBackupSets()
{
  this.ListOfBackupSetInfo.Clear();
  foreach (string fullFile in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory))
  {
    string[] fileArray = fullFile.Split(new char[] { '\\' });
    string file = fileArray[fileArray.GetUpperBound(0)];
    if (file.EndsWith(".backupset"))
    {
      BackupSetInfo si = (BackupSetInfo)DeserializeXml(file, typeof(BackupSetInfo));
      this.ListOfBackupSetInfo.Add(si);
    }
  }
}

private object DeserializeXml(string FileName, Type ObjectType)
{
  using (FileStream fs = new FileStream(FileName, FileMode.Open))
  {
    using (XmlDictionaryReader reader = 
	XmlDictionaryReader.CreateTextReader(fs, XmlDictionaryReaderQuotas.Max))
    {
      XmlSerializer serializer = new XmlSerializer(ObjectType);
      return serializer.Deserialize(reader);
    }
  }
}

Backup is performed with a recursive copy method. Files are counted first to get an accurate progress bar measurement.

C#
private void CopyDirectory(DirectoryInfo Source, 
	DirectoryInfo Destination, bool CountOnly)
{
  foreach (FileInfo f in Source.GetFiles())
  {
    if (CountOnly)
      this.TotalFiles++;
    else
    {
      f.CopyTo(Destination + @"\" + f.Name);
      this.CopiedFiles++;
    }
  }
  foreach (DirectoryInfo dS in Source.GetDirectories())
  {
    string newDirPart = dS.FullName.Replace(Source.FullName, "");
    string newDestinationPath = Destination + newDirPart;
    DirectoryInfo dD = new DirectoryInfo(newDestinationPath);
    dD.Create();
    CopyDirectory(dS, dD, CountOnly);
  }
}

backup_progress.PNG

Backup progress. Backup is performed on a separate thread to keep the UI responsive.

C#
public partial class frmProgress : System.Windows.Forms.Form
{
  Backup backup = new Backup();
  private BackupSetInfo settingsInfo = new BackupSetInfo();
  private static BackupResponseInfo response = new BackupResponseInfo();
  private Thread t;
  public delegate void BackupFinishedDelegate();

  public frmProgress(BackupSetInfo SettingsInfoOf)
  {
    InitializeComponent();
    settingsInfo = SettingsInfoOf;
  }

  private void ProcessError(Exception ex)
  {
    this.Cursor = Cursors.Arrow;
    MessageBox.Show(ex.Message + "\r\n" + ex.ToString());
  }

  private void btnDo_Click(object sender, System.EventArgs e)
  {
    timer1.Enabled = false;

    if (btnDo.Text.ToLower().StartsWith("cancel"))
      t.Abort();
    this.Close();
  }

  private void frmProgress_Load(object sender, System.EventArgs e)
  {
    t = new Thread(delegate() { BackupStart(this.settingsInfo); });
    t.Start();
    timer1.Enabled = true;
  }

  private void BackupStart(BackupSetInfo SettingsInfoOf)
  {
    response = backup.BackupFiles(SettingsInfoOf);
    
    this.Invoke(new BackupFinishedDelegate(BackupFinished));
  }

  private void BackupFinished()
  {
    lblStatus.Text = response.Message;
    btnDo.Text = "OK";
  }

  private void timer1_Tick(object sender, EventArgs e)
  {
    this.progressBar1.Maximum = backup.TotalFiles;
    if(backup.CopiedFiles<=progressBar1.Maximum)
      this.progressBar1.Value = backup.CopiedFiles;
  }
}

backup_files.PNG

Backed up files. test2 is the name of this backup set. It is appended with the date and time.  As can be seen, it preserves the file locations.

History

  • 20th November, 2008: Version 1

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Sage Software
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNice utility! Thank you. Pin
Espiritu12-May-11 6:28
Espiritu12-May-11 6:28 
Nice utility! Thank you.
GeneralGood article Pin
Donsw13-Dec-08 11:38
Donsw13-Dec-08 11:38 
GeneralCool !!! Pin
Ashutosh Phoujdar25-Nov-08 0:11
Ashutosh Phoujdar25-Nov-08 0:11 
GeneralRe: Cool !!! Pin
Micah Burnett25-Nov-08 4:06
Micah Burnett25-Nov-08 4:06 
GeneralNice! Pin
ivan.bolcina24-Nov-08 21:22
ivan.bolcina24-Nov-08 21:22 
GeneralRe: Nice! Pin
Micah Burnett25-Nov-08 4:16
Micah Burnett25-Nov-08 4:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.