Question

I'm writing an Excel file recovery program with VB.Net that tries to be a convenient place to gather and access Microsoft's recommended methods. If your interested in my probably kludgy, error filled, and lacking enough cleanup code it's here: http://pastebin.com/v4GgDteY. The basic functionality seems to work although I haven't tested graph macro table recovery yet.

It occurred to me that Vista and Windows 7 users could benefit from being offered a list of previous versions of the file within my application if the Shadow Copy Service is on and there are previous copies. How do I do this?

I looked at a lot of web pages but found no easy to crib code. One possibility I guess would be to use vssadmin via the shell but that is pretty cumbersome. I just want to display a dialogue box like the Previous Versions property sheet and allow users to pick one of the previous versions. I guess I could just display the previous version property sheet via the shell by programmatically invoking the context menu and the "Restore previous versions choice", however I also want to be able to offer the list for Vista Home Basic and Premium Users who don't have access to that tab even though apparently the previous versions still exist. Additionally if it possible I would like to offer XP users the same functionality although I'm pretty sure with XP only the System files are in the shadow copies.

I looked at MSDN on the Shadow Copy Service and went through all the pages, I also looked at AlphaVSS and AlphaFS and all the comments. I'm kind of guessing that I need to use AlphaVss and AlphFS and do the following?

  1. Find out the list of snapshots/restore points that exist on the computer.
  2. Mount those snapshots.
  3. Navigate in the mounted volumes to the Excel file the user wants to recover and make a list of those paths.
  4. With the list of paths handy, compare with some kind of diff program, the shadow copies of the files with the original.
  5. Pull out the youngest or oldest version (I don't think it matters) of those shadow copies that differ from the recovery target.
  6. List those versions of the files that are found to be different.

This seems cumbersome and slow, but maybe is the fastest way to do things. I just need some confirmation that is the way to go now.

Was it helpful?

Solution

I finally decided to go ahead and start coding. Please make suggestions for speeding up the code or what do with files that are found to be different from the recovery file target. Is there a simpler way to do this with AlphaVSS and AlphaFS?

Private Sub Button1_Click_2(sender As System.Object, e As System.EventArgs) Handles Button1.Click

    'Find out the number of vss shadow snapshots (restore 
    'points). All shadows apparently have a linkable path 
    '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy#,
    'where # is a simple one, two or three digit integer.
    Dim objProcess As New Process()
    objProcess.StartInfo.UseShellExecute = False
    objProcess.StartInfo.RedirectStandardOutput = True
    objProcess.StartInfo.CreateNoWindow = True
    objProcess.StartInfo.RedirectStandardError = True
    objProcess.StartInfo.FileName() = "vssadmin"
    objProcess.StartInfo.Arguments() = "List Shadows"
    objProcess.Start()

    Dim burp As String = objProcess.StandardOutput.ReadToEnd
    Dim strError As String = objProcess.StandardError.ReadToEnd()
    objProcess.WaitForExit()
    Dim xnum As Integer = 0
    Dim counterVariable As Integer = 1
    ' Call Regex.Matches method.
    Dim matches As MatchCollection = Regex.Matches(burp, _
                            "HarddiskVolumeShadowCopy")
    ' Loop over matches.
    For Each m As Match In matches
        xnum = xnum + 1
        'At the max xnum + 1 is the number of shadows that exist
    Next
    objProcess.Close()

    Do
        'Here we make symbolic links to all the shadows, one at a time 
        'and loop through until all shadows are exposed as folders in C:\.
        Dim myProcess As New Process()
        myProcess.StartInfo.FileName = "cmd.exe"
        myProcess.StartInfo.UseShellExecute = False
        myProcess.StartInfo.RedirectStandardInput = True
        myProcess.StartInfo.RedirectStandardOutput = True
        myProcess.StartInfo.CreateNoWindow = True
        myProcess.Start()
        Dim myStreamWriter As StreamWriter = myProcess.StandardInput
        myStreamWriter.WriteLine("mklink /d C:\shadow" & counterVariable _
            & " \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy" _
            & counterVariable & "\")
        myStreamWriter.Close()
        myProcess.WaitForExit()
        myProcess.Close()

        ' Here I compare our recovery target file against the shadow copies
        Dim sFile As String = PathTb.Text
        Dim sFileShadowPath As String = "C:\shadow" & _
            counterVariable & DelFromLeft("C:", sFile)
        Dim jingle As New Process()
        jingle.StartInfo.FileName = "cmd.exe"
        jingle.StartInfo.UseShellExecute = False
        jingle.StartInfo.RedirectStandardInput = True
        jingle.StartInfo.RedirectStandardOutput = True
        jingle.StartInfo.CreateNoWindow = True
        jingle.Start()
        Dim jingleWriter As StreamWriter = jingle.StandardInput
        jingleWriter.WriteLine("fc """ & sFile & """ """ _
                               & sFileShadowPath & """")
        jingleWriter.Close()
        jingle.WaitForExit()
        Dim jingleReader As StreamReader = jingle.StandardOutput
        Dim JingleCompOut As String = jingleReader.ReadToEnd
        jingleReader.Close()
        jingle.WaitForExit()
        jingle.Close()
        Dim jingleBoolean As Boolean = JingleCompOut.Contains( _
            "no differences encountered").ToString
        If jingleBoolean = "True" Then
            MsgBox(jingleBoolean)
        Else
            'I haven't decided what to do with the paths of 
            'files that are different from the recovery target.
            MsgBox("No")
        End If

        counterVariable = counterVariable + 1
    Loop Until counterVariable = xnum + 1

End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top