Click here to Skip to main content
6,630,586 members and growing! (17,574 online)
Email Password   helpLost your password?
Desktop Development » Files and Folders » Utilities     Intermediate License: The Code Project Open License (CPOL)

Backup Utility

By Micah Burnett

A simple OO backup utility that preserves full file paths
C#.NET 2.0, WinXP, Win2003, Vista, WinForms, Dev, SysAdmin
Posted:20 Nov 2008
Views:9,033
Bookmarked:40 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
10 votes for this article.
Popularity: 3.78 Rating: 3.78 out of 5

1
1 vote, 10.0%
2
4 votes, 40.0%
3
2 votes, 20.0%
4
3 votes, 30.0%
5
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

[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.

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.

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.

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.

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)

About the Author

Micah Burnett


Member

Occupation: Software Developer (Senior)
Company: Sage Software
Location: United States United States

Other popular Files and Folders articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 5 of 5 (Total in Forum: 5) (Refresh)FirstPrevNext
GeneralGood article PinmemberDonsw12:38 13 Dec '08  
GeneralCool !!! Pinmemberashu fouzdar1:11 25 Nov '08  
GeneralRe: Cool !!! PinmemberMicah Burnett5:06 25 Nov '08  
GeneralNice! Pinmemberivan.bolcina22:22 24 Nov '08  
GeneralRe: Nice! PinmemberMicah Burnett5:16 25 Nov '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 20 Nov 2008
Editor: Deeksha Shenoy
Copyright 2008 by Micah Burnett
Everything else Copyright © CodeProject, 1999-2009
Web21 | Advertise on the Code Project