KnowDotNet NetRefactor

Auto Saving Project Items

by Les Smith
Print this Article Discuss in Forums

Microsoft Word has an auto save capability and Visual Studio .NET does not.  Is there a way to implement auto save in an add-in?  In this article I will show you a Class to automatically save all changed project items at a user specified time interval.  If you have ever had your computer hang or crash and you realize that you have been coding for an hour and have lost your code, this type of functionality will suddenly become invaluable.

To implement auto save functionality, I will instantiate a class when the add-in is started and it will automatically save at the interval that I specify.  First, I will show the code required in the Connect class of the add-in and then show the code for the auto save class itself.

In the declaration section of the Connect class of your add-in, place the following declaration.  I only dimension the object here, because I want the activation of the functionality to be optional, based on a registry or configuration file setting.

  Public Shared objAutoSave As CAutoSave

In the OnConnection method of the connect class, I will place the following code.  It checks a registry setting that determines the number of minutes at which the class is to auto save project items.  If the setting is set to zero, I will not activate the auto save class.  I use a setup form in my add-ins and this registry setting is one of the parameters that I would be able to set from the setup dialog.  If the value of AutoSave is greater than zero, I instantiate the object and pass two parameters to the constructor.  The first is the application object, which I have saved in an object named oVS.  The second parameter is the number of minutes between auto saves.

  ' if autosave is configured to run, start it up
  Dim iMinutes As Integer = _
     GetSetting(
Me.APP_TITLE, Me.SETTINGS, "AutoSave", 0)

  
If iMinutes > 0 Then
     objAutoSave = New CAutoSave(oVS, iMinutes)
  
End If

The code for the auto save class will be displayed and documented below.  The code is commented.

Imports Extensibility
Imports EnvDTE
Imports System.Timers

Public Class CAutoSave
  
Public SaveTimeInMinutes As Integer
   Private oVB As EnvDTE.DTE
  
WithEvents AutoSaveTimer As New System.Timers.Timer()

This is the main method and is responsible for saving the open documents.  Obviously, any windows that are not open do not need to be saved.

   Public Sub SaveAllDirtySolutionObjects()
      
Dim docs As Documents
      
Dim doc As Document
      
Dim prj As Project
      
Dim prjs As Projects
      
Dim SBar As EnvDTE.StatusBar
      
Dim i As Integer
      Dim count As Integer
      Try
         Dim sln As Solution = oVS.Solution

         SBar = oVS.StatusBar
    
        
If Not sln Is Nothing Then
            ' get count of the number of open documents.
            ' only open windows can be dirty
            count = oVS.Documents.Count
            i = 1

            
' loop through the open documents
            
For Each doc In oVS.Documents
              
' a little flash for the audience, update the
               ' IDE status bar as the windows are saved

               SBar.Progress(
True, "AutoSaving " & doc.Name, i, count)
               SBar.SetLineColumnCharacter(i, count, 0)
               i += 1

              
' save the current document if dirty
              
If Not doc.Saved Then
                  doc.Save(doc.FullName)
              
End If
            Next

            ' save the projects
            ' this sometimes fails so ignore the error
            For Each prj In sln.Projects
              
Try
                  prj.Save(prj.FullName)
               Catch
               End Try
            Next
         End If

         ' All done, so get rid of the bar.
         SBar.Progress(False)
        
Exit Sub
      Catch
      End Try
   End Sub

This is the class constructor.  It accepts two parameter, previously described, and initiates an object of the System Timer class.  The timer will fire at intervals set by the parameter passed from the OnConnection method.

   Public Sub New(ByRef roVS As EnvDTE.DTE, _
      
ByVal MinutesToSave As Integer)
      oVS = roVS
      
Me.SaveTimeInMinutes = MinutesToSave
      
Me.AutoSaveTimer.Interval = Me.SaveTimeInMinutes * 60 * 1000
      AutoSaveTimer.Enabled =
True
   End Sub


This event handles the firing of the timer.  It checks to see if the user has turned off the timer from the setup dialog.  If so, it does not save.

   Private Sub AutoSaveTimer_Elapsed(ByVal sender As Object, _
    
ByVal e As System.Timers.ElapsedEventArgs) _
    
Handles AutoSaveTimer.Elapsed
      
' user could have changed the save time or turned off auto save
      If Me.SaveTimeInMinutes <> 0 Then
         SaveAllDirtySolutionObjects()
        
Me.AutoSaveTimer.Interval = Me.SaveTimeInMinutes * 60 * 1000
      
Else
         Me.AutoSaveTimer.Interval = 0
        
Me.AutoSaveTimer.Enabled = False
      End If
   End Sub

   Protected Overrides Sub Finalize()
      
MyBase.Finalize()
      
Try
         Me.AutoSaveTimer.Enabled = False
         Me.AutoSaveTimer.Interval = 0
         AutoSaveTimer =
Nothing
      Catch
      End Try
   End Sub
End
Class

Back to Top


Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing