Click here to Skip to main content
14,177,048 members
Click here to Skip to main content
Add your own
alternative version


68 bookmarked
Posted 7 Jan 2008
Licenced Ms-PL

Volume Shadow Copies from .NET

, 7 Jan 2008
Rate this:
Please Sign up or sign in to vote.
Use the Windows Volume Shadow Copy service from .NET.


If you want to automatically make backup copies of locked files, such as Microsoft Outlook PST files, you'll find that your options seem limited to dedicated backup utilities such as Microsoft Backup. But what if you want to backup only your PST files, and you want the backup copy to be immediately accessible, not compressed in a BKF file?

Microsoft Volume Shadow Copy Service is the solution to this problem. It's how Microsoft Backup and other backup utilities are able to make copies of locked files.

There's a Volume Shadow Copy service SDK and documentation on MSDN but it is by no means clear how to implement VSC using .NET, or even if it's possible. With a little help from Craig Andera's blog, I have found that it is, and I show you how, here below.


When I first started looking into Volume Shadow Copy, I wasn't really sure where to begin. I thought I might need to create and register a provider. But then one of the commenters to Craig Andera's HOBOCOPY blog posting referenced a VSSCoordinatorClass which turned out to be exactly what I needed.

The VSSCoordinatorClass doesn't seem to be documented. If I Google it, I get the original blog comment plus one or two other unofficial and not particularly helpful references. MSDN doesn't say anything about it either. This class does seem to expose the methods of the IVssBackupComponents interface, which is what you need to create shadow copies.

In particular, to create a volume shadow copy, here are the steps you need to take:

  1. Create a snapshot set using StartSnapshotSet
  2. Add a volume to the snapshot set using AddToSnapshotSet
  3. Initialize the volume snapshot using the DoSnapshotSet
  4. Wait until QueryStatus indicates that the snapshot has been initialized
  5. Get the volume name of the snapshot using GetSnapshotProperties
  6. Use the FindFile and CopyFile APIs to access the shadow volume
  7. When done, use the DeleteSnapshots method to indicate that the shadow volume is no longer needed

Using the code

The attached source code is a simple utility that scans a source directory and any subdirectories for PST files. Any PST files found are copied to a target directory.

To use the utility, extract the files from the Zip file. Run makeshadowcopy.exe with the following parameters:

  • -F: indicates the "from" directory. I.e.: C:\Documents and Settings\ttyree\Local Settings\Application Data\Microsoft\Outlook
  • -T: indicates the "to" directory. I.e.: C:\tedsoutlookbackup

Note that these two Windows services are, by default, set to "manual", and will need to be started for Volume Shadow Copy to work:

  • Volume Shadow Copy service
  • MS Software Shadow Copy Provider

Much of the code in the sample utility is standard, and I won't try to explain how the FindFirstFile and CopyFile APIs are used. I did encapsulate the Volume Shadow Copy as a class and am posting it here for your perusal:

The class is instantiated with a volume name (e.g.: "C:" or "E:"), and once instantiated, the DeviceName property will return the name of the shadow volume. When done with the shadow volume, release it using the Delete method.

Public Class Snapshot
    'Note:  The following two windows services are stopped by default.
    '       For volume shadow copy to function
    '       they need to be started.

    '       Volume Shadow Copy service
    '       MS Software Shadow Copy Provider

    'Technet article describing how Volume Shadow Copy works:
    '     2b0d2457-b7d8-42c3-b6c9-59c145b7765f1033.mspx?mfr=true

    'Thanks to Craig Andera for his HOBOCOPY blog 
    'posting which provided the basis for this code.

    'Note: More information about programming 
    '      the volume shadow copy service is available here:

    'Note: The microsoft volume shadow copy service 
    '      SDK with headers and utilties is available here:
    '     FamilyID=0B4F56E4-0CCC-4626-826A-ED2C4C95C871&displaylang=en

    Private Const VSS_E_BAD_STATE = &H80042301
    Private Const VSS_E_PROVIDER_ALREADY_REGISTERED = &H80042303
    Private Const VSS_E_PROVIDER_NOT_REGISTERED = &H80042304
    Private Const VSS_E_PROVIDER_VETO = &H80042306
    Private Const VSS_E_PROVIDER_IN_USE = &H80042307
    Private Const VSS_E_OBJECT_NOT_FOUND = &H80042308
    Private Const VSS_S_ASYNC_PENDING = &H42309
    Private Const VSS_S_ASYNC_FINISHED = &H4230A
    Private Const VSS_S_ASYNC_CANCELLED = &H4230B
    Private Const VSS_E_VOLUME_NOT_SUPPORTED = &H8004230C
    Private Const VSS_E_OBJECT_ALREADY_EXISTS = &H8004230D
    Private Const VSS_E_UNEXPECTED_PROVIDER_ERROR = &H8004230F
    Private Const VSS_E_CORRUPT_XML_DOCUMENT = &H80042310
    Private Const VSS_E_INVALID_XML_DOCUMENT = &H80042311
    Private Const VSS_E_FLUSH_WRITES_TIMEOUT = &H80042313
    Private Const VSS_E_HOLD_WRITES_TIMEOUT = &H80042314
    Private Const VSS_E_UNEXPECTED_WRITER_ERROR = &H80042315
    Private Const VSS_E_SNAPSHOT_SET_IN_PROGRESS = &H80042316
    Private Const VSS_E_WRITER_INFRASTRUCTURE = &H80042318
    Private Const VSS_E_WRITER_NOT_RESPONDING = &H80042319
    Private Const VSS_E_WRITER_ALREADY_SUBSCRIBED = &H8004231A
    Private Const VSS_E_UNSUPPORTED_CONTEXT = &H8004231B
    Private Const VSS_E_VOLUME_IN_USE = &H8004231D
    Private Const VSS_E_INSUFFICIENT_STORAGE = &H8004231F
    Private Const VSS_E_NO_SNAPSHOTS_IMPORTED = &H80042320

    Private moSnapshotSetID As New Guid
    Private moSnapshotID As New Guid
    Private msDeviceName As String

    Public Sub New(ByVal sVolume As String)
        Dim vss As New VSS.VSSCoordinatorClass

        MakeNewSnapshot(vss, sVolume, moSnapshotSetID, moSnapshotID)
        msDeviceName = GetSnapshotDeviceName(vss, moSnapshotID)
    End Sub

    Public ReadOnly Property DeviceName() As String
            Return msDeviceName
        End Get
    End Property

    Private Sub MakeNewSnapshot( _
                ByRef vss As VSS.VSSCoordinatorClass, _
                ByVal sVolume As String, _
                ByRef output_SnapShotSetID As Guid, _
                ByRef output_SnapShotID As Guid)

        vss.AddToSnapshotSet(sVolume, Guid.Empty, output_SnapShotID)

        Dim ovssAsync As VSS.IVssAsync = Nothing
        Dim oCallBack As Object = Nothing

        vss.DoSnapshotSet(oCallBack, ovssAsync)

        Do While (True)
            Dim hr As Integer = 0
            Dim x As Integer = 0

            ovssAsync.QueryStatus(hr, x)

            If hr = VSS_S_ASYNC_FINISHED Then
                Exit Do
            End If


    End Sub

    Private Function GetSnapshotDeviceName( _
                    ByRef vss As VSS.VSSCoordinatorClass, _
                    ByVal oSnapShotID As Guid) As String

        Dim sDeviceName As String = ""

        Dim osnapshotProps As New VSS._VSS_SNAPSHOT_PROP
        vss.GetSnapshotProperties(oSnapShotID, osnapshotProps)
        sDeviceName = osnapshotProps.m_pwszSnapshotDeviceObject

        Return sDeviceName
    End Function

    Private Sub Abort( _
                ByRef vss As VSS.VSSCoordinatorClass)

        '   Aborting VSS Operations

        '---Only one snapshot can be operating at a time,
        '   so abort any current snapshots.

    End Sub

    Public Sub Delete()
        Dim iCountOfDeletedSnapshots As Integer = 0
        Dim oNonDeletedSnapshotID As New Guid

        Dim vss As New VSS.VSSCoordinatorClass
        vss.DeleteSnapshots( _
                moSnapshotSetID, _
                True, _
                iCountOfDeletedSnapshots, _
    End Sub
End Class

Possible improvements

There's a lot that could be done here, and top of the list is better error handling. Only one shadow volume can be open at a time, and if any sort of error is encountered while the app is attempting to initialize the shadow volume, it will crash with an ugly error message. Handling this and other likely errors would be a great step forward.

Other improvements relate more to the scope of the PST backup utility. Since I included this utility mostly as a demo of what Volume Shadow Copies are good for, such improvements are beyond the scope of this project.


This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


About the Author

Joe Lynds
Web Developer
United States United States
Joe is a software engineer. He lives in Pennsylvania where he develops software for manufacturing and human services when he is not at the park with his three boys.

You may also be interested in...

Comments and Discussions

QuestionHow do I add a reference to VSS? Pin
tolsen6425-Jul-15 9:25
membertolsen6425-Jul-15 9:25 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey18-Feb-12 3:11
professionalManoj Kumar Choubey18-Feb-12 3:11 
General Pin
Uwe Keim5-Jan-10 1:58
sitebuilderUwe Keim5-Jan-10 1:58 
QuestionUsing the MakeShadowCopy Class Pin
pecka200515-Sep-08 4:21
memberpecka200515-Sep-08 4:21 
GeneralAlphaVSS - A library for working with VSS in .NET Pin
Antrillion24-Aug-08 12:24
memberAntrillion24-Aug-08 12:24 
QuestionHow can we do VSS Incremental and Differential Backup in C++? Pin
Neeraj B.2-Jul-08 21:01
memberNeeraj B.2-Jul-08 21:01 
AnswerRe: How can we do VSS Incremental and Differential Backup in C++? Pin
warad_yo20-Apr-10 0:00
memberwarad_yo20-Apr-10 0:00 
NewsShadow Copy on Vista (WMI) Pin
sergvi18-Jun-08 8:13
membersergvi18-Jun-08 8:13 
GeneralRe: Shadow Copy on Vista (WMI) Pin
Lojikl2-Aug-08 5:19
memberLojikl2-Aug-08 5:19 
NewsVSS asynchronous operation was canceled by timeout [modified] Pin
sergvi25-May-08 20:10
membersergvi25-May-08 20:10 
Newsugly error message in VSS Pin
sergvi23-May-08 3:23
membersergvi23-May-08 3:23 
QuestionInterop.VSS.dlll Pin
HendrikVanIperen3-Apr-08 14:05
memberHendrikVanIperen3-Apr-08 14:05 
GeneralRe: Interop.VSS.dlll Pin
Scott Holmes7-Apr-08 7:30
memberScott Holmes7-Apr-08 7:30 
GeneralRe: Interop.VSS.dlll Pin
HendrikVanIperen7-Apr-08 8:11
memberHendrikVanIperen7-Apr-08 8:11 
GeneralRe: Interop.VSS.dlll Pin
Member 200768010-Apr-08 5:29
memberMember 200768010-Apr-08 5:29 
GeneralRe: Interop.VSS.dlll Pin
Scott Holmes22-Apr-08 6:19
memberScott Holmes22-Apr-08 6:19 
QuestionVery Cool --- But there are some issues Pin
Lojikl27-Mar-08 18:33
memberLojikl27-Mar-08 18:33 
AnswerRe: Very Cool --- But there are some issues Pin
SimeBP15-Nov-09 12:38
memberSimeBP15-Nov-09 12:38 
QuestionOne small question: Where can I find the referenced vss.dll? [modified] Pin
mahop23-Mar-08 10:06
membermahop23-Mar-08 10:06 
QuestionDoes any have this working on Vista? Pin
timkelly200322-Feb-08 4:11
membertimkelly200322-Feb-08 4:11 
AnswerRe: Does any have this working on Vista? Pin
leetrax28-Feb-08 2:31
memberleetrax28-Feb-08 2:31 
GeneralRe: Does any have this working on Vista? Pin
Scott Holmes14-Mar-08 3:42
memberScott Holmes14-Mar-08 3:42 
AnswerRe: Does any have this working on Vista? Pin
Evren Daglioglu18-Mar-08 5:46
memberEvren Daglioglu18-Mar-08 5:46 
GeneralSnapshot Set Deleted When .NET .exe shutdown (even if delete not called) Pin
Member 200768014-Feb-08 19:08
memberMember 200768014-Feb-08 19:08 
GeneralThanks ... Pin
leetrax28-Jan-08 22:50
memberleetrax28-Jan-08 22:50 

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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190526.1 | Last Updated 7 Jan 2008
Article Copyright 2008 by Joe Lynds
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid