Introduction
Have you ever screwed up the code of your project and needed to revert to a past version?
Unfortunatelly, Microsoft Visual Studio doesn’t has a backup option. If you need to do so, you have to manually copy your solution folder to another folder or media.
Tired of doing that, I decided to make a backup macro: my goal was to add a context menu option to Solution Explorer, to automatate the process of copying its files to the destination location.
How It works
As described above, this adds an item to the solution context menu(named ‘Make backup’).
When this option is selected, it cleans the solution’s temporary files, then copies it’s folder contents to a destination with the following format:
F:BACKUPSolution Namemonth-day-year hour:minute:second
The F:BACKUP folder name is hardcoded in the macro and must be changed to your backup destination folder.
Installation and Use
First you have to add the macro code to the Microsoft Visual Studio IDE. This is easily done from the Tools->Macros->Macro IDE menu.
Now, as stated above, you have to change the destination folder, which is hard coded in the macro as an optional parameter. I use F:BACKUP, which is in an external USB Hard Drive.
Then, you need to create the context menu item that calls the macro:
- Open Tools->Customize menu
- Select Commands tab
- Check “Context Menu” radio button, then select “Project and Solution Context Menu | Solution”
- Click on Add Command button
- Select Macros on the menu of the left
- Select the created macro from the menu on the right(Macros.MyMacros.Backup.Make) and click OK
- Now the option is added, but with the name of the macro. I changed it to “Make backup” from the Change Selection button
And you are done, now you can click in your solution and select the new item in the context menu to automatically make a backup of it.
Source code
Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports EnvDTE90a Imports EnvDTE100 Imports System.Diagnostics Imports System.IO Public Module Backup Public Sub Make(Optional ByVal backupdir As String = "F:BACKUP") Dim SolutionExplorer As UIHierarchy Dim Item As UIHierarchyItem Dim Solution As EnvDTE.SolutionClass Dim SourceFolder As String, TargetFolder As String If Not Directory.Exists(backupdir) Then MsgBox("Cannot access destination folder(" + backupdir + ")", MsgBoxStyle.Critical, "Backup copy") Exit Sub End If SolutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object() For Each Item In SolutionExplorer.SelectedItems Solution = CType(Item.Object, EnvDTE.SolutionClass) If Solution.SolutionBuild.BuildState = vsBuildState.vsBuildStateInProgress Then MsgBox("Cannot make backup while building solution", MsgBoxStyle.Critical, "Backup copy") Exit Sub End If Solution.SolutionBuild.Clean(True) SourceFolder = Path.GetDirectoryName(Solution.FullName) TargetFolder = Path.Combine(backupdir, Solution.Properties.Item("Name").Value) Directory.CreateDirectory(TargetFolder) TargetFolder = TargetFolder + "" + Format(Now, "MM-dd-yy HH_MM_ss") If Not CopyDir(SourceFolder, TargetFolder) Then MsgBox("Destination folder already exists. Backup aborted", MsgBoxStyle.Critical, "Backup copy") Exit Sub End If MsgBox("Backup done succesfully", MsgBoxStyle.Information, "Backup copy") Next End Sub Private Function CopyDir(ByVal source As String, ByVal target As String) As Boolean Dim diSource As DirectoryInfo Dim diTarget As DirectoryInfo diSource = New DirectoryInfo(source) diTarget = New DirectoryInfo(target) Return CopyDir(diSource, diTarget) End Function Private Function CopyDir(ByVal source As DirectoryInfo, ByVal target As DirectoryInfo, Optional ByVal AllowCreate As Boolean = False) As Boolean Dim fi As FileInfo Dim di As DirectoryInfo, td As DirectoryInfo If AllowCreate Then If Not Directory.Exists(target.FullName) Then Directory.CreateDirectory(target.FullName) Else If Directory.Exists(target.FullName) Then Return False End If Directory.CreateDirectory(target.FullName) For Each fi In source.GetFiles() fi.CopyTo(Path.Combine(target.ToString(), fi.Name), True) Next For Each di In source.GetDirectories() td = target.CreateSubdirectory(di.Name) CopyDir(di, td, True) Next Return True End Function End Module
Conclusion
I hope you find this code as useful as I do. It was only tested in Visual Studio 2010, but I think that it should work in previous versions.