AlphaVSS – Bringing Windows Shadow Copy Service (VSS) to .NET

Programming using the Windows Volume Shadow Copy Service (VSS) on the .NET platform in  C# (or VB) seems to be somewhat problematic to say the least.  I have read numerous posts online about this issue, without ever finding a robust solution that would allow me to access the VSS API from within my .NET application. (See also my previous post).

A long discussion about these issues can for example be found in the post Announcing Hobocopy, and several others are available online, so I won’t go into that here.

The solution however, seems to be to write a custom wrapper in managed C++, that provides a managed interface that can be used from .NET and C#.  There are quite a few interfaces and enumerations and the likes, so it is not a project one particularly would like to do, but for some reason I took it upon myself to do this.

So here is AlphaVSS 0.5 alpha. It is distributed under the MIT license and can be freely used by anyone according to the terms in that license.

Currently it is completely undocumented, but that should not pose to much of a problem, since MSDN has extensive documentation on the VSS API. AlphaVSS just wraps the interfaces of the VSS API in managed classes. The few items below should be enough to use the library with only the documentation found on MSDN.

  • The Interfaces of the VSS API is exposed as classes in AlphaVSS. So IVssBackupComponents becomes VssBackupComponents, IVssSnapshotProp becomes VssSnapshotProp and so on.
  • Enumerations are CamelCased, so eg. _VSS_SNAPSHOT_CONTEXT becomes VssSnapshotContext. In addition, the values defined in the enumerations are also CamelCased and any prefix removed. So VSS_CTX_FILE_SHARE_BACKUP becomes FileShareBackup.
  • Errors are handled by exceptions and not return codes.
  • Some methods return a value instead of using an out parameter. This should be clear from the method signature.
  • The IVssBackupComponents::QuerySnapshot interface is changed somewhat. It returns an IEnumerable<IVssObjectProp>. IVssObjectProp is a common interface to the VssSnapshotProp and VssProviderProp classes, providing the Type accessor. This is instead of the cumbersom enumeration interface available in the original COM interfaces.
  • … any additional things you may find.

The use of the same signatures in most methods (or pretty similar ones anyway) is not the best way to design things in C# or .NET in general, and I will probably improve the interface and make it conform more to common C# design practices to further simplify its use in .NET.

Please remember that this library currently is not very well tested, it is still in early alpha state. But all the tests I’ve performed seem to work just fine.

The solution and project files supplied are for Visual Studio 2008.

Please leave a comment and tell me if you find this useful or if you discover any bugs.

The latest version of the library can be downloaded from the Downloads page.

43 Comments

  1. For anyone still reading here, the windows compatibility issues should be resolved with version 0.8. Please report any failures or successes in using it (on the CodePlex message-board please, not here :)

  2. I really hope to get around to this windows compatibility issues shortly. If you guys find out anything, please keep me posted on your findings.

    And please note that I moved the projects to CodePlex, so please continue any further discussion there.

    (And please keep the comments coming :)

  3. Hi,

    I’m getting what Nic Bedford is getting. XP is fine but on Vista x64, compiling as an x86 app i’m getting an ‘Unexpected System Error’ exception with a HRESULT of 0×80131501. Any ideas?

    Nic! did you have any luck solving this.

  4. Hi,

    I don’t know how many different dll’s there actually needs to be. I have finally gotten around to actually installing VMWare with most current versions of Windows (2003, XP, Vista and 2008, both x86 and x64) and hopefully I will get around to testing this in a short while. It is my guess that the compiler flags are not correctly checked for anything but XP and Vista currently, but as I said, I’m hoping to be able to fix this shortly.

    (I recently got a job so unforunately I have much less time at my disposal, but I will get around to it =)

  5. This looks excellent. I need DLL for Server 2008 and Swerver 2003. Do i actually need to compile the Source against the SDK on the actual operating system, or is it just a compilation flag that needs to be set ….

    Thanks for all your efforts and I’ll let you know how the integration of this goes into latest software.

    Cheers.

  6. Beautiful work, it looks like this fills in a gap that I was fearing. I am currently running Win 2008, Vista 64, and XP on boxes with compilers. I am going to explore some and I will try to provide feedback as I make the attempts.

  7. Recently I have been completely occupied with finishing my master thesis project, looking for a job and so on, so I have not had the time to write sample apps or write an article at Code Project. Hopefully I will get time to do this soon.

    Regarding the 64-bit problems I have no idea unfortunately, since I haven’t tried 64-bit development yet.

  8. Nice work, hope you continue and toss in some sample apps, have you thougt about posting to Code Project?

    Todd

  9. Hi DeCaf,

    I have been using AlphaVSS some more, and everything is working ok in my program on x86 Vista, but when I try and run on x64 Vista i am getting problems.

    I know there are issues with 64 bit process’ can’t load a 32 bit dll etc…

    So I set the build type to be x86 in my program, but when i call

    [code]InitializeForBackup(null);[/code]

    I get an ‘Unexpected System Error’ exception with a HRESULT of 0x80131501. Any ideas?

  10. It depends… either there are no snapshots in your system, or you need to set the vss context to VssSnapshotContext.All before performing the query to retrieve all snapshots. (This may not work on Windows XP however, I am unsure of that). Refer to the official VSS documentation on MSDN for details on what is supported on what platform.

    Hope this helps!

  11. I’ve just come across AlphaVSS, and it looks like it may be useful for a project I am working on, however I’ve hit a stumbling block before I’ve even got up and running :(

    I’m simply trying to query the current snapshots on my system, with the following code:

    using (VssBackupComponents vss = new VssBackupComponents())
    {
    vss.InitializeForBackup(null);

    foreach (VssSnapshotProp snapshot in vss.Query(VssObjectType.Snapshot))
    {
    // read snapshot properties
    }
    }

    But I don’t appear to get anything back in the VssSnapshotProp variable

    Any ideas?

  12. Hi Adam,

    Well, accessing the snapshot can of course be done in several ways. On Vista you can expose a snapshot as a drive letter through the Vss API. On XP it is possible as well, using the DefineDosDevice API call, but this is a more cumbersome solution and requires you to use P/Invoke. Of course you can also use P/Invoke to invoke the native Win32 API functions to access the path you get from Vss (\\?\GLOBALROOT\Device\VolumeShadowCopy5\… etc).

    But the simplest solution that I know of, if you are new to C# would probably be to use AlphaFS (or something similar if you can find it), since .NET does not natively support accessing such paths.

    Hope this helps.

  13. Hi,

    Looks like exactly the library I need.

    I’m a C# newbie and am working on a backup program to copy .PST files.

    I’m able to create a snapshot using DeCaf’s code snippet before but do I need AlphaFS to actually access files within that snapshot?

    //Adam

  14. That is a problem of course. I do not have access to Win2003SP2 or Server2008 so I am not sure what needs to be done to fix it. The Server 2008 should be the easiest, and I would have thought compiling for that would work out of the box. I was aware there might be some problems for Win2003. Perhaps you could let me know what the errors are when you try to compile it, and we could try to work this out together?

    So send me a mail with the errors and we’ll try to take it from there. (And Swedish will work too ;)

    // Peter

    mail: peter (dot) palotas (at) gmail (dot) com

  15. Hi

    Got a little problem. Im not very used to C++ coding (been a while), so I tried your precompiled binaries.
    I develop on a Vista machine, and there it works fine, but when running the program on a Win2003SP2 och Server2008 i receive Tonys first error “A procedure imported by ‘AlpahVSS…”

    I tried to compile it myself, by changeing the vista release config, and changed the NTDDI_VERSION and _WIN32_WINNT, but then I just got errors in the compilationprocess….

  16. Hey Decaf, I wasn’t initializing the backupcomponent (to null) so that’s why it was throwing the errors. I thought I had to actuall have the xml before I did something like that. It’s working alright now. Now I just have to get all the parameters in the right places to do an actual backup. Great work though. AlphaFS looks like it will come in very handy too.

  17. What type of exceptions are you getting by the way? VSS is rather picky about doing things in the right order it seems, so it is fairly easy to get a VssBadStateException when doing things out of order.

    (Oh, and by the way, the code above of course has no error-checking and a bunch of stuff that should be in production code, but that should be fairly obvious ;)

  18. Yes, I tried a backup on XP, and it works without a problem here.

    Try the following code snippet, which should simply create a shadow copy of c:\

            static void Main(string[] args)
            {
                using (VssBackupComponents vss = new VssBackupComponents())
                {
                    vss.InitializeForBackup(null);
                    vss.SetBackupState(false, true, VssBackupType.Full, false);
                    using (VssAsync async = vss.GatherWriterMetadata())
                        async.Wait();
                    vss.StartSnapshotSet();
                    vss.AddToSnapshotSet(@"c:\", Guid.Empty);
                    using (VssAsync async = vss.DoSnapshotSet())
                        async.Wait();
                }
            }
  19. Wow, you work fast. Your 0.7.0 works much better because I can now create a vssbackupcomponents variable without it failing on me but everything from that point on throws an exception. If I view the vssbackupcomponent variable in the debugger, everything pretty much throws an exception. I’m wondering if I’m skipping a step before creating a vssbackupcomponent variable but it looks like I’m not because I am strictly going by what is documented. Have you tried a backup on xp yet?

  20. Well, not too much code changes, mainly some stuff to deal with missing constants and functions in the XP version. I didn’t want two different managed interfaces, so all methods and enumerations are the same in both versions now, however the unsupported methods on XP will throw NotSupportedException. All documented in the API documentation.

    Also decided to provide a binary release as well this time, to simplify things somewhat. All available in the freshly released 0.7.0 release. Hope this will work better for you =)

  21. Decaf, I see you came to the same conclusion I came to. After compiling vshadow like you suggested I figured out I would need to compiled AlphaVSS against the VSS SDK 7.2 vssapi.lib. I thought there would be problems but I didn’t think there would be many code changes on your side of things. Hopefully it’s doable. Thanks for working on it.

  22. Okay, I finally found the problem. A bit difficult to find information on it, but it seems the VSS API changed between windows versions (and they did not just add stuff to it). So to successfully compile for Windows XP, it seems you cannot link against the vssapi.lib in the Windows SDK v6.1, but you will have to use the VSS SDK 7.2 vssapi.lib and headers instead.

    However this will unfortunately lead to a great number of compilation errors because of undefined symbols and unresolved externals in AlphaVSS as it stands now. I’m working on fixing the problem, and a version that will work also on Windows XP should not be too far away.

    Thank you for pointing this problem out to me. Guess that’s the downside of developing on Vista! ;)

  23. Tony, I was actually able to reproduce the problem you described with VS2008 Express on Windows XP, so the problem is not with your code. I will continue to investigate this tomorrow, and hopefully find out what is going on. I will keep you posted!

  24. I’ll have to try out the new version 0.6.0 today but I don’t think that will solve my problems. Plus I need to try out the vshadow program and see if I can compile that too. I don’t know why I haven’t tried that already. It could just be my VS installation. Since I’m in a XPsp3 VS2008express enviornment, my header includes are pointing to files from Windows(Vista)SDK6.1, Win2003R2SDK, and the project directory. My libs are point to those places as well plus a althunk.lib from windows driver development kit. I could probably solve this by updating to VS2008profesional version. Don’t go through the trouble of reproducing the error, I really don’t think it has to do with your code. I’ll try the vshadow program tonight and see where I get with that.

  25. Thank you for you encouraging words. It helps to keep motivation up. I think I’ve come to a point where the interface should have stabilized and aside from any problems that I have not yet discovered, the library should be getting close to a usable or beta stage. And the same goes for AlphaFS.

    Now all I need are people using it to find bugs! (not that I ever produce bugs, but still ;)

  26. Only just saw the AlphaFS posting now.. Thanks!

    I think you did a great job.. I saw your posting on the HoboCopy blog too.. I think AlphaVSS would have made been a great help to that project too.

    Will keep you posted if I come across anything.

    Thanks again.

  27. That doesn’t sound good. What version of windows are you using (including any service packs)? I’d like to see if I can reproduce the problem. Also, can you use the vshadow program from the Windows SDK without problems?

    Anyway, thanks for letting me know. Your feedback is important!

  28. Actually, I’ve been actively trying to use it but got stuck on some sort of dependency error. AlphaVSS compiles just fine with C++ 2008 express edition but when I try to use the dll in a c# project, I get this error: “A procedure imported by ‘AlpahVSS, Version=0.5.1.28, Culture=neutral, PublicKeyToken=null’ could not be loaded.” with the innerexception saying “The specified procedure could not be found. (Exception from HRESULT: 0x8007007F)”. It’s failing on the line “vsbackup = new Alphaleonis.Win32.VSS.VssBackupComponents();” I’ve used dependency walker but fail to see what could be the problem.

  29. Well, apart from your comments on the initial release, I haven’t heard anything from anyone. So I’m starting to believe there may not be much interested in this library after all.

  30. I was just about to start building a mananged vss api myself today. I’ll have to try out your API. This page is probably going to get popular really fast.

  31. Thanks for the hint. I’ll try it as soon as I can.
    Also looking forward to the file operation library you mentioned. I guess it will be a great help to me too.
    Cheers

  32. By the way, what version of the Windows SDK are you using? Seems these constants should be defined regardless on what platform you are compilling on I think?

  33. There are two options as I see it. Either define these enumerations using the actual values defined by these constants, or probably better, to wrap them in #if/#endif sections checking the value of _WIN32_WINNT eliminating them if the platform on which the library is currently compiled does not support them.

    I will probably add the latter to the library.

    The various windows versions and constants used can be found here: http://msdn.microsoft.com/en-us/library/aa383745.aspx

    Seems they thought of a new scheme of determining the versions again… nothing like good ol’ consistency! ;)

  34. Thanks for your reply.. In fact yes, I’m compiling on XP.
    Will look into that and get back.

  35. Hi, and thanks for your comments and interest. As I mentioned it is still in early alpha, so there is still some work to be done for sure. I am still working on a sample application to test the library, but as I said, everything I’ve tried so far seems to work (creating/removing shadow copies straight from .NET).

    The undeclared identifiers are a little strange to me, but it may be you either don’t have the latest SDK, or possibly that you’re not compiling for Vista. I know that some VSS services are only supported under Vista. I will look into that.

    Exposing shadows as drive-letters under XP can not be done except via the DefineDosDevice API as you mentioned as far as I know, which is a problem. However I have actually also created a library for this purpose providing the functionality to access paths in the form \\?\GLOBALROOT\Device\HardDiskShadowCopy. I don’t know why .NET doesn’t support this, because the functionality is available from every function in the Win32 API it seems, so accessing these paths is just a matter of standard p/invoke to the Win32 API standard filesystem functions. I will likely release this library here as well in a short while to assist with this functionality. (That library also exposes the support for transacted file operations on NTFS systems, which may be useful).

  36. Looks great!
    So, just to check if I understood correctly, I can create/remove a snapshot straight from managed code… however, I assume that this will result in a shadow copy available as \\?\GLOBALROOT\Device\HardDiskShadowCopy etc… right?

    This would still leave the problem that .NET cannot read directly from these UNC paths .. whenever I try that I get the exception “Paths that begin with \\?\GlobalRoot are internal to the kernel and should not be opened by managed applications.”

    I’m still looking for a decent way to make the shadow copy accessible in .NET. I’ve come across the DefineDosDevice API, but it worked a bit shakily for me and it’s hardly the robust link one would expect to rely on.

    Did you have better luck in this regard?

    Also on a separate note, when compiling straight out of the box I get 5 errors of the type:
    VSS_BS_WRITER_SUPPORTS_PARALLEL_RESTORES: undelclared identifier.

    The other 4 are:
    VSS_RME_RESTORE_STOP_START
    VSS_BS_WRITER_SUPPORTS_PARALLEL_RESTORES
    VSS_RME_RESTORE_STOP_START
    VSS_E_WRITER_STATUS_NOT_AVAILABLE

    Any idea.

    Thanks and well done once again, seems to be real need for something like this.

    Julian

Comments are closed.