en-UShe-IL
You are here:   Blog
Register   |  Login

Blog Archive:

Maximize
* Can be used in order to search for older blogs Entries

Search in blogs


Blog Categories:

Maximize
* Can be used in order to search for blogs Entries by Categories

Blog Tags:

Maximize
* Can be used in order to search for blogs by keywords

TNWikiSummit


Awared MVP 


 


Microsoft® Community Contributor 


Microsoft® Community Contributor


 Read first, before you you use the blog! Maximize
ינו9

Written by: ronen ariely
09/01/2014 00:30 RssIcon

AlphaVSS is a Dot.NET class library providing a managed API for the Volume Shadow Copy Service (VSS). AlphaVSS is written in C# and C++/CLI and released under the MIT license. AlphaVSS duplicates the original VSS API (quite closely) and act as a wrapper to the VSS API for the use of Dot.Net developing.

* You can get additional information on the VSS in English at the following link, or in Hebrew in this link.

In this blog I will show and explain the basic use of AlphaVSS, using several examples, ordered from the simple to the more complex ones. Please review the code thoroughly from the first code to last. Explanations and clarifications in the code and mast be reading from the first example.

As always :-) Use the code and the tutorial at your own risk!
Make sure you understand what you are doing, before executing any unknown code. Some code's examples are designed for actions that might harm your system! DO Not Execute any testing or learning codes on active servers!

Have fun :-)

Sample one:  Console application Using Dot.Net Framework version 4 with  build in AlphaVSS NuGet Package

1. Creating New Project.

    * Open Visual Studio As Administrator!

    * Chose create new project type "Console application"

    * Use Dot.Net 4 framework

    * named the project Ariely_AlphaVSS_Sample01

2. Add NuGet Package named alphavss

use the search on-line option and look for alphavss. Install the package.

3. Go over the Code's comment and understand it!!!

After you are ready, Copy this code into "Main" method.

// Getting information on the files to copy (This is not part of the VSS action)
String _Source1 = @"C:\_ISUG_VSS_DB\20140106_ISUG_VSS_DB.mdf";
String _Source2 = @"C:\_ISUG_VSS_DB\20140106_ISUG_VSS_DB_log.ldf";
String _Destination = @"V:\QQ";
FileInfo MyFileInfo = new FileInfo(_Source1);
String _Volume = MyFileInfo.Directory.Root.Name;
 
// VSS step 1: Initialize
IVssImplementation _vssImplementation = VssUtils.LoadImplementation();
IVssBackupComponents _backup = _vssImplementation.CreateVssBackupComponents();
_backup.InitializeForBackup(null);
 
// VSS step 2: Getting Metadata from all the VSS writers
_backup.GatherWriterMetadata();
 
// VSS step 3: VSS Configuration
_backup.SetContext(VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease);
_backup.SetBackupState(false, true, Alphaleonis.Win32.Vss.VssBackupType.Full, false);
 
// VSS step 4: Declaring the Volumes that we need to use in this beckup.
// The Snapshot is a volume element (Here come the name "Volume Shadow-Copy")
// For each file that we nee to copy we have to make sure that the propere volume is in the "Snapshot Set"
Guid MyGuid01 = _backup.StartSnapshotSet();
Guid MyGuid02 = _backup.AddToSnapshotSet(_Volume, Guid.Empty);
 
// VSS step 5: Preparation (Writers & Provaiders need to start preparation)
_backup.PrepareForBackup();
// VSS step 6: Create a Snapshot For each volume in the "Snapshot Set"
_backup.DoSnapshotSet();
 
/***********************************
/* At this point we have a snapshot!
/* This action should not take more then 60 second, regardless of file or disk size.
/* THe snapshot is not a backup or any copy!
/***********************************/
 
// VSS step 7: Expose Snapshot
/***********************************
/* Snapshot path look like:
 * \\?\Volume{011682bf-23d7-11e2-93e7-806e6f6e6963}\
 * The build in method System.IO.File.Copy do not work with path like this,
 * Therefor, we are going to Expose the Snapshot to our application,
 * by mapping the Snapshot to new virtual volume
 * - Make sure that you are using a volume that is not already exist
 * - This is only for learning purposes. usually we will use the snapshot directly as i show in the next example in the blog
/***********************************/
_backup.ExposeSnapshot(MyGuid02, null, VssVolumeSnapshotAttributes.ExposedLocally, "L:");
 
// VSS step 8: Copy Files!
/***********************************
/* Now we start to copy the files/folders/disk!
/* Execution time can depend on what we are copying
/* We can copy one element or several element.
/* As long as we are working under the same snapshot,
/* the element should be in consist state from the same point-in-time
/***********************************/
String sVSSFile1 = _Source1.Replace(_Volume, @"L:\");
String sVSSFile2 = _Source2.Replace(_Volume, @"L:\");
if (File.Exists(sVSSFile1))
    System.IO.File.Copy(sVSSFile1, _Destination + @"\" + System.IO.Path.GetFileName(_Source1), true);
if (File.Exists(sVSSFile2))
    System.IO.File.Copy(sVSSFile2, _Destination + @"\" + System.IO.Path.GetFileName(_Source2), true);
 
// VSS step 9: Delete the snapshot (using the Exposed Snapshot name)
foreach (VssSnapshotProperties prop in _backup.QuerySnapshots())
{
    if (prop.ExposedName == @"L:\")
    {
        Console.WriteLine("prop.ExposedNam Found!");
        _backup.DeleteSnapshot(prop.SnapshotId, true);
    }
}
 
_backup = null;
 
Console.WriteLine("END OK. Click any Key to close the application");
Console.ReadLine();

4. add "using Alphaleonis.Win32.Vss;" & "using System.IO;"

using System.IO;
using Alphaleonis.Win32.Vss;

5. Download

You can get the project here

Sample Two:  Using Dot.Net Framework version 2-3.5

At this time as I know, there is no built-in NuGet package for Dot.Net framework lower then version  4. that is not a problem :-) At the project web site we can download the code and compile it for any version we want, or we can download a DLL libraries prepared for different versions of Dot.Net.

1. download AlphaVSS Dll version 1.1.4000.3 for Dot.NET 2-3.5

Unzip the File

2. Creating New Project.

    * Open Visual Studio As Administrator!

    * Chose create new project type "Console application"

    * Use Dot.Net 3.5 framework

    * named the project Ariely_AlphaVSS_Sample02

3. Add the Dll files to the project

    * Solution Explorer -> right click on Refrences -> Add Refrences

    * On the new windows chose "Browse..." button.

   * Browse to the folder where you unzip the AlphaVSS

   * Chose all the DLL files (Not the exe files!) and chose OK

4. Adding the Code

Go to Sample one and continue with step 3 to the end

Sample Three:  Using Dot.Net Framework version 2-3.5 on Old Version of AlphaVSS DLL Libraries


This code use several small upgrades. let's start with the code first and I will add some example latter on....

THIS BLOG IS UNDER WRITTEN!
Need to add some explainig for sample three, add sample four which named duplicati and can be download from the site project at http://www.duplicati.com/, and add some explanation on the duplicati project...
Basically you have all the codes or links here...

Module mMain
 
    Private Declare Auto Function CopyFileEx Lib "kernel32.dll" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal lpProgressRoutine As CopyProgressRoutine_Delegate, ByVal lpData As Int32, ByVal lpBool As Int32, ByVal dwCopyFlags As Int32) As Integer
 
    Private Delegate Function CopyProgressRoutine_Delegate(
                                                          ByVal totalFileSize As Long,
                                                          ByVal totalBytesTransferred As Long,
                                                          ByVal streamSize As Long,
                                                          ByVal streamBytesTransferred As Long,
                                                          ByVal dwStreamNumber As Int32,
                                                          ByVal dwCallbackReason As Int32,
                                                          ByVal hSourceFile As Int32,
                                                          ByVal hDestinationFile As Int32,
                                                          ByVal lpData As Int32
                                                          ) As Long
 
    Private m_oCPR As CopyProgressRoutine_Delegate
 
    Sub Main()
 
        '
        ' Display Setting
        Console.BackgroundColor = ConsoleColor.White
        Console.Clear()
        Console.SetWindowSize(90, 30)
        Console.SetWindowPosition(0, 0)
        Console.ForegroundColor = ConsoleColor.DarkGreen
        ' Prevent example from ending if CTL+C is pressed.
        Console.TreatControlCAsInput = True
 
StartPoint:
 
        Console.Clear()
        Console.WriteLine("*******************************************************************")
        Console.WriteLine("**                                                               **")
        Console.WriteLine("** Greetings,                                                    **")
        Console.WriteLine("**                                                               **")
        Console.WriteLine("** This small app is only for primary basic Testing              **")
        Console.WriteLine("** of VSS using Dot.Net Technology                               **")
        Console.WriteLine("** The app is base on the AlphaVSS open project:                 **")
        Console.Write("** ")
        Console.ForegroundColor = ConsoleColor.Blue
        Console.Write("http://www.codeplex.com/alphavss")
        Console.ForegroundColor = ConsoleColor.DarkGreen
        Console.WriteLine("                              **")
        Console.WriteLine("**                                                               **")
        Console.WriteLine("** The application is designed only for internal purposes!!      **")
        Console.WriteLine("** In no way use on production servers.                          **")
        Console.Write("** ")
        Console.ForegroundColor = ConsoleColor.DarkRed
        Console.Write("Any use is at your own risk!!!")
        Console.ForegroundColor = ConsoleColor.DarkGreen
        Console.WriteLine("                                **")
        Console.WriteLine("**                                                               **")
        Console.WriteLine("** Have Fun,                                                     **")
        Console.WriteLine("** Ariely Ronen                                                  **")
        Console.WriteLine("** ____________________________________________________________  **")
        Console.WriteLine("**                                                               **")
        Console.WriteLine("** Do you want to start the TEST                                 **")
        Console.WriteLine("** by selecting the file you want to copy? (y/n)                 **")
        Console.WriteLine("**                                                               **")
        Console.WriteLine("*******************************************************************")
 
        Dim MyConsoleKeyInfo As ConsoleKeyInfo
        MyConsoleKeyInfo = Console.ReadKey()
        If Not (MyConsoleKeyInfo.Key.ToString() = "Y") Then Return
 
SelectFileToCopy:
 
        Console.Clear()
        Console.Write("Starting Test Ver 0.01")
 
 
        Dim sDestFolder As New FolderBrowserDialog
        Dim sDestFolderPath As String
 
        sDestFolder.Description = "Select a destination folder (where the file will be copy to)."
        ' Do not show the button for new folder
        sDestFolder.ShowNewFolderButton = False
        Dim dlgResult As DialogResult = sDestFolder.ShowDialog()
        If dlgResult = Windows.Forms.DialogResult.OK Then
            sDestFolderPath = sDestFolder.SelectedPath
        Else
            sDestFolderPath = My.Computer.FileSystem.SpecialDirectories.MyDocuments.ToString()
        End If
 
        Dim oOFD As New OpenFileDialog
        Dim sFileName As String
 
        ' copy progress handler
        ' we add the function "CopyProgressRoutine" to the Delegate "CopyProgressRoutine_Delegate"
        ' so every time the event come the function run
        m_oCPR = New CopyProgressRoutine_Delegate(AddressOf CopyProgressRoutine)
 
        oOFD.ValidateNames = False
        oOFD.Title = "Select an in-use file you would like to copy."
        oOFD.Filter = "All files (*.*)|*.*"
        If oOFD.ShowDialog = DialogResult.OK Then
            sFileName = oOFD.FileName
 
            Console.Clear()
            Console.WriteLine("File to Copy: ")
            Console.WriteLine(sFileName)
            Console.WriteLine()
            Console.WriteLine("The file will be copy to:")
            Console.WriteLine(sDestFolderPath)
            Console.WriteLine()
 
            Console.WriteLine("Press any key to continue.")
            Console.ReadKey()
            Console.Clear()
 
            ' Lets Start to copy
            PerformVSSCopy(sFileName, sDestFolderPath)
        End If
 
        Console.WriteLine()
        Console.WriteLine("Press 1 to go to Start Point,2 to go to Select new File To Copy, any other key to exit.")
        MyConsoleKeyInfo = Console.ReadKey()
        Select Case MyConsoleKeyInfo.Key.ToString()
            Case "D1"
                GoTo StartPoint
            Case "D2"
                GoTo SelectFileToCopy
            Case Else
 
        End Select
 
    End Sub
 
    Private Function CopyProgressRoutine(
                                        ByVal totalFileSize As Long,
                                        ByVal totalBytesTransferred As Long,
                                        ByVal streamSize As Long,
                                        ByVal streamBytesTransferred As Long,
                                        ByVal dwStreamNumber As Int32,
                                        ByVal dwCallbackReason As Int32,
                                        ByVal hSourceFile As Int32,
                                        ByVal hDestinationFile As Int32,
                                        ByVal lpData As Int32
                                        ) As Int32
        Dim dPerc As Double = 100
 
        If totalFileSize <> 0 Then dPerc = (totalBytesTransferred / totalFileSize) * 100
 
        Console.CursorLeft = 0
        Console.Write("Copied " & totalBytesTransferred & " of " & totalFileSize & " [" & Format(dPerc, "0.0") & "%]")
    End Function
 
    Private Sub PerformVSSCopy(ByVal sFilename As String, ByVal sDestFolder As String)
        ' Based on the documention from
        ' and the help of those on
 
        ' The parts I have marked and INFO ONLY are not required for the
        ' VSS Copy to work, they just give insight into the process
 
        Dim oVSSImpl As Alphaleonis.Win32.Vss.IVssImplementation
        Dim oVSS As Alphaleonis.Win32.Vss.IVssBackupComponents
        Dim sVolume As String
        Dim oFI As New IO.FileInfo(sFilename)
        Dim gSnapshot As Guid
        Dim gSnapshotSet As Guid
        Dim sVSSFile As String
        Dim sDestFile As String
        Dim oProps As Alphaleonis.Win32.Vss.VssSnapshotProperties
 
        Try
 
            ' Load the Implementation specifi for this machine i.e Windowx XP , Vista, 32 or 64 Bit
            oVSSImpl = Alphaleonis.Win32.Vss.VssUtils.LoadImplementation()
 
            ' This is the main man for VSS Backups.
            Console.WriteLine("Initializing VssBackupComponents Object")
            oVSS = oVSSImpl.CreateVssBackupComponents
            oVSS.InitializeForBackup(Nothing)
 
            ' Tell VSS that we are requesting a backup with particular options
            Console.WriteLine("Setting Backup State")
            oVSS.SetBackupState(False, True, Alphaleonis.Win32.Vss.VssBackupType.Full, False)
 
            ' Tell all VSS Writers that we want their MetaData. We wait until all Writers have responded.
            Console.WriteLine("Gat Writers Metadata")
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.GatherWriterMetadata()
                async.Wait()
            End Using
            ' INFO ONLY : Enumerate who responded to our GatherWriterMetadata request
 
            ' Create the Snapshot Set that we will place all our Snapshotted volumes into. (even tho here will only snapshot one volume)
            Console.WriteLine("Starting Snapshot Set")
            gSnapshotSet = oVSS.StartSnapshotSet()
 
            ' Add a Snapshot for the required Volume
            sVolume = oFI.Directory.Root.Name
            Console.WriteLine("Add To Snapshot Set the Volume: " & sVolume)
            gSnapshot = oVSS.AddToSnapshotSet(sVolume, Guid.Empty)
 
            ' Notify all VSS Writers that the backup is about to start, we wait untuil they have indicated they are ready.
            Console.WriteLine("VSS Writers Prepare For Backup .")
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.PrepareForBackup()
                async.Wait()
            End Using
 
            'Request that the Snapshot are created and wait until they are ready.
            Console.WriteLine("Do Snapshot Set [this can take some time]")
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.DoSnapshotSet
                async.Wait()
            End Using
             
            ' --------------------------------------------------------------
            ' --------------------------------------------------------------
            ' Now we can start copying the file.
            ' --------------------------------------------------------------
            ' We need the properties to tell us how to access our files in the snapshot
            oProps = oVSS.GetSnapshotProperties(gSnapshot)
            sVSSFile = sFilename.Replace(sVolume, oProps.SnapshotDeviceObject & "\")
            sDestFile = IO.Path.Combine(sDestFolder, IO.Path.GetFileName(sFilename))
 
            ' INFO ONLY Lets check the Properties of the snapshot set
 
            ' Copy, but the normal .NET routines will not work here. Back to the API !!!
            Console.WriteLine("Copying file using API Routines.")
            Console.WriteLine()
            CopyFileEx(sVSSFile, sDestFile, m_oCPR, 0, 0, 0)
            Console.WriteLine()
            Console.WriteLine("Done !")
            ' --------------------------------------------------------------
            ' --------------------------------------------------------------
 
            ' Release the snapshot set, we could also just call Dispose on the VssBackupComponents object
            ' For clarity, I'll do both here.
            Console.WriteLine("Deleting Snapshot Set.")
            oVSS.DeleteSnapshotSet(gSnapshotSet, True)
 
        Catch ex As Exception
            Console.WriteLine()
            Console.WriteLine(ex.Message)
            Console.WriteLine(ex.StackTrace)
            Console.WriteLine()
 
        Finally
            oVSS.Dispose()
        End Try
    End Sub
 
    '''
    ''' Determines if we can use the usual file operations to copy this file. I.E It is not a locked or inaccessbile file.
    '''
    '''
    '''
    '''
    Private Function CanOpenFileNormaly(ByVal sFileName As String) As Boolean
        Dim bRet As Boolean
        Dim oStr As IO.FileStream
 
        Try
            oStr = New IO.FileStream(sFileName, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
            oStr.Close()
            bRet = True
 
        Catch ex As Exception
            bRet = False
        End Try
 
        Return bRet
    End Function
 
End Module


5. Download


This Project include several old AlphaVSS DLL files, which i did not complied myself!!! I do not remember where i got them. It is highly recommended to adjust this code for the new Version of AlphaVSS.


I can not be responsible for what those files includes or if it has harmful code! I can say that I execute this project on multiple systems without any problem.

You can download this project here

.

.

http://alphavss.codeplex.com/

http://ariely.info/Blog/tabid/83/EntryId/136/VOLUME-SHADOW-COPY-SERVICE-SQL-Server-Writer.aspx

http://technet.microsoft.com/en-us/library/ee923636.aspx