示例#1
0
        /// <summary>
        /// This stage initializes both the requester (this program) and
        /// any writers on the system in preparation for a backup and sets
        /// up a communcation channel between the two.
        /// </summary>
        void InitializeBackup()
        {
            // Here we are retrieving an OS-dependent object that encapsulates
            // all of the VSS functionality.  The OS indepdence that this single
            // factory method provides is one of AlphaVSS's major strengths!
            IVssImplementation vss = VssUtils.LoadImplementation();

            // Now we create a BackupComponents object to manage the backup.
            // This object will have a one-to-one relationship with its backup
            // and must be cleaned up when the backup finishes (ie. it cannot
            // be reused).
            //
            // Note that this object is a member of our class, as it needs to
            // stick around for the full backup.
            _backup = vss.CreateVssBackupComponents();

            // Now we must initialize the components.  We can either start a
            // fresh backup by passing null here, or we could resume a previous
            // backup operation through an earlier use of the SaveXML method.
            _backup.InitializeForBackup(null);

            // At this point, we're supposed to establish communication with
            // the writers on the system.  It is possible before this step to
            // enable or disable specific writers via the BackupComponents'
            // Enable* and Disable* methods.
            _backup.GatherWriterMetadata();
        }
示例#2
0
        public void Delete(ISnapshot sn)
        {
            Logger.Append(Severity.DEBUG, "Deleting snapshot " + sn.Path + " (id " + sn.Id + ")");
            if (!OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
            {
                // Deleting is unnecessary on XP since snaps are non-persistent
                // and automatically released on Disposing VSS objects.
                return;
            }


            try{
                IVssImplementation vssi = VssUtils.LoadImplementation();
                using (IVssBackupComponents oVSS = vssi.CreateVssBackupComponents()){
                    oVSS.InitializeForBackup(null);
                    oVSS.SetContext(VssSnapshotContext.All);
                    oVSS.DeleteSnapshot(sn.Id, true);
                }

                Logger.Append(Severity.INFO, "Deleted snapshot " + sn.Path + " (id " + sn.Id + ")");
            }
            catch (Exception vsse) {
                Logger.Append(Severity.WARNING, "Unable to delete snapshot " + sn.Path + " (id " + sn.Id + "): " + vsse.Message);
                //backup.Dispose();
                throw vsse;
            }
        }
示例#3
0
        public static void CopyFile(string from, string to)
        {
            FileInfo MyFileInfo = new FileInfo(from);
            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();

            _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 = from.Replace(_Volume, @"L:\");

            if (File.Exists(sVSSFile1))
            {
                System.IO.File.Copy(sVSSFile1, to + @"\" + System.IO.Path.GetFileName(from), 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;
        }
示例#4
0
        /// <summary>
        /// For all Hyper-V guests it enumerate all associated paths using VSS data
        /// </summary>
        /// <returns>A collection of VMs and paths</returns>
        private Dictionary <string, List <string> > GetAllVMsPathsVSS()
        {
            var ret = new Dictionary <string, List <string> >();

            //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC
            string             alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss");
            string             alphadll = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
            IVssImplementation vss      = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");

            using (var m_backup = vss.CreateVssBackupComponents())
            {
                m_backup.InitializeForBackup(null);
                m_backup.SetContext(VssSnapshotContext.Backup);
                m_backup.SetBackupState(false, true, VssBackupType.Full, false);
                m_backup.EnableWriterClasses(new Guid[] { HyperVWriterGuid });

                try
                {
                    m_backup.GatherWriterMetadata();
                    var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(HyperVWriterGuid));

                    if (writerMetaData == null)
                    {
                        throw new Exception("Microsoft Hyper-V VSS Writer not found - cannot backup Hyper-V machines.");
                    }

                    foreach (var component in writerMetaData.Components)
                    {
                        var paths = new List <string>();

                        foreach (var file in component.Files)
                        {
                            if (file.FileSpecification.Contains("*"))
                            {
                                if (Directory.Exists(Utility.Utility.AppendDirSeparator(file.Path)))
                                {
                                    paths.Add(Utility.Utility.AppendDirSeparator(file.Path));
                                }
                            }
                            else
                            {
                                if (File.Exists(Path.Combine(file.Path, file.FileSpecification)))
                                {
                                    paths.Add(Path.Combine(file.Path, file.FileSpecification));
                                }
                            }
                        }

                        ret.Add(component.ComponentName, paths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList());
                    }
                }
                finally
                {
                    m_backup.FreeWriterMetadata();
                }
            }

            return(ret);
        }
示例#5
0
 public CloneOSMigrationStep(ILogger <CloneOSMigrationStep> logger,
                             IOperatingSystemHelper osHelper,
                             IFileSystemHelper fileSystemHelper,
                             MigrationFlowData migrationData,
                             IVssImplementation vss) : base(migrationData)
 {
     this.logger           = logger;
     this.osHelper         = osHelper;
     this.fileSystemHelper = fileSystemHelper;
     this.vss = vss;
 }
示例#6
0
            private void Initialize(string Volume, bool IncludeBootableSystemState)
            {
                //string filename = @"C:\Windows\system32\config\sam";
                //FileInfo fiSource = new FileInfo(filename);
                //String Volume = fiSource.Directory.Root.Name;

                // VSS step 1: Initialize
                IVssImplementation   vss    = VssUtils.LoadImplementation();
                IVssBackupComponents backup = vss.CreateVssBackupComponents();

                backup.InitializeForBackup(null);

                // VSS step 2: Getting Metadata from all the VSS writers
                backup.GatherWriterMetadata();

                // VSS step 3: VSS Configuration
                backup.SetContext((VssVolumeSnapshotAttributes)0);
                backup.SetBackupState(false, IncludeBootableSystemState, 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 (hence the name "Volume Shadow-Copy").
                // For each file that we nee to copy we have to make sure that the proper volume is included in the "Snapshot Set".
                Guid SetGuid    = backup.StartSnapshotSet();
                Guid VolumeGuid = 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!
                 * /* please more information at http://technet.microsoft.com/en-us/library/ee923636.aspx
                 * /***********************************/

                // 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,
                 * Therefore, 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
                 * /***********************************/

                VssSnapshotProperties SnapshotProperties = backup.GetSnapshotProperties(VolumeGuid);
                DirectoryInfo         diShadowRoot       = new DirectoryInfo(SnapshotProperties.SnapshotDeviceObject);

                DirectoryInfo[] Folders = diShadowRoot.GetDirectories();
            }
示例#7
0
        void InitializeBackup()
        {
            IVssImplementation vss = VssUtils.LoadImplementation();

            _backup = vss.CreateVssBackupComponents();
            _backup.InitializeForBackup(null);

            using (IVssAsync async = _backup.GatherWriterMetadata())
            {
                async.Wait();
            }
        }
        public VolumeShadowCopy(string VolumeName)
        {
            IVssImplementation vss = VssUtils.LoadImplementation();

            BackupComponents = vss.CreateVssBackupComponents();
            BackupComponents.InitializeForBackup(null);
            BackupComponents.GatherWriterMetadata();
            BackupComponents.FreeWriterMetadata();
            SetId = BackupComponents.StartSnapshotSet();
            AddVolume(Path.GetPathRoot(VolumeName));
            BackupComponents.SetBackupState(false, true, VssBackupType.Full, false);
            BackupComponents.PrepareForBackup();
        }
示例#9
0
        public bool IsVolumeSnapshottable(string volumeName)
        {
            IVssImplementation vssImplementation = VssUtils.LoadImplementation();

            using (IVssBackupComponents backup = vssImplementation.CreateVssBackupComponents()){
                backup.InitializeForBackup(null);
                using (IVssAsync async = backup.GatherWriterMetadata()){
                    async.Wait();
                    async.Dispose();
                }
                return(backup.IsVolumeSupported(volumeName));
            }
        }
示例#10
0
        // This stage initializes both the requester and any writers on the system in
        // preparation for a backup, and sets up a communication channel between the two.
        private void InitializeBackup()
        {
            // Retrieving an OS-dependent object that encapsulates all of the VSS functionality.
            IVssImplementation vss = VssUtils.LoadImplementation();

            // Now we create a BackupComponents object to manage the backup.
            _backup = vss.CreateVssBackupComponents();

            // Now we must initialize the components. We can either start a fresh backup by passing null here.
            _backup.InitializeForBackup(null);

            // Establish communication with the writers on the system. It is possible before this step to
            // enable or disable specific writers via the BackupComponents' Enable* and Disable* methods.
            _backup.GatherWriterMetadata();
        }
示例#11
0
文件: VSS.cs 项目: radtek/BackO
        public VSS(BackupLevel level)
        {
            this.RestorePosition    = RestoreOrder.AfterStorage;
            this.ExplodedComponents = new List <string>();
            Metadata  = new SPOMetadata();
            BasePaths = new List <BasePath>();
            IVssImplementation vss = VssUtils.LoadImplementation();

            backup = vss.CreateVssBackupComponents();
            //Logger.Append(Severity.DEBUG, "0/6 Initializing Snapshot ("+ ((BasePaths == null)? "NON-component mode" : "component mode")+")");
            backup.InitializeForBackup(null);
            VssBackupType vssLevel = VssBackupType.Full;

            if (level == BackupLevel.Full)
            {
                vssLevel = VssBackupType.Full;
            }
            else if (level == BackupLevel.Refresh)
            {
                vssLevel = VssBackupType.Incremental;
            }

            /*	else if (level == BackupLevel.Differential)
             *                      vssLevel = VssBackupType.Differential;*/
            else if (level == BackupLevel.TransactionLog)
            {
                vssLevel = VssBackupType.Log;
            }
            //if(spoPaths == null) // component-less snapshot set
            //		backup.SetBackupState(false, true, VssBackupType.Full, false);
            //else
            backup.SetBackupState(true, true, vssLevel, false);
            if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
            {
                // The only context supported on Windows XP is VssSnapshotContext.Backup
                backup.SetContext(VssSnapshotContext.AppRollback);
            }
            //Logger.Append(Severity.DEBUG, "1/6 Gathering writers metadata and status");
            using (IVssAsync async = backup.GatherWriterMetadata()){
                async.Wait();
                async.Dispose();
            }
            // gather writers status before adding backup set components
            using (IVssAsync async = backup.GatherWriterStatus()){
                async.Wait();
                async.Dispose();
            }
        }
示例#12
0
        void InitializeBackup()
        {
            IVssImplementation vss = VssUtils.LoadImplementation();

            Debug.WriteLine("vss interface implementation called - vssutils.loadimplementation() called");
            thisBackup = vss.CreateVssBackupComponents();
            Debug.WriteLine("backup component created");
            //try
            //{
            thisBackup.InitializeForBackup(null);
            thisBackup.GatherWriterMetadata();
            //}
            //catch (Alphaleonis.Win32.Vss.VssUnexpectedErrorException ue)
            //{
            //    Debug.WriteLine("AlphaVss Unexpected Error: " + ue);
            // }
        }
示例#13
0
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.RegisterType <MigratorEngine>();
            builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
            .Where(t => t.Name.EndsWith("MigrationStep"))
            .InstancePerDependency();

            builder.RegisterType <FileSystemHelper>().AsImplementedInterfaces();
            builder.RegisterType <FileCopyHelper>().AsImplementedInterfaces().InstancePerDependency();
            builder.RegisterType <OperatingSystemHelper>().AsImplementedInterfaces();
            builder.RegisterType <FileSystem>().AsImplementedInterfaces();
            IVssImplementation vss = VssUtils.LoadImplementation();

            builder.RegisterInstance(vss).AsImplementedInterfaces();
        }
示例#14
0
        static void BackupFile(string srcPath, string destPath)
        {
            srcPath = Path.GetFullPath(srcPath);

            IVssImplementation vssImpl = VssUtils.LoadImplementation();

            using (IVssBackupComponents vss = vssImpl.CreateVssBackupComponents())
            {
                vss.InitializeForBackup(null);

                vss.SetBackupState(true, true, VssBackupType.Full, false);
                vss.SetContext(VssSnapshotContext.FileShareBackup);

                using (IVssAsync async = vss.GatherWriterMetadata())
                    async.Wait();

                Guid vssSet = vss.StartSnapshotSet();

                var rootPath   = Path.GetPathRoot(srcPath);
                var snapshotId = vss.AddToSnapshotSet(rootPath, Guid.Empty);

                using (IVssAsync async = vss.DoSnapshotSet())
                    async.Wait();

                try
                {
                    var snapshotPath = vss.GetSnapshotProperties(snapshotId).SnapshotDeviceObject;

                    var pathNoRoot = srcPath.Substring(rootPath.Length);
                    var path       = Path.Combine(snapshotPath, pathNoRoot);

                    if (File.Exists(destPath))
                    {
                        File.Delete(destPath);
                    }
                    Alphaleonis.Win32.Filesystem.File.Copy(path, destPath);
                }
                finally
                {
                    vss.DeleteSnapshotSet(vssSet, true);
                }
            }
        }
示例#15
0
        static void Main(string[] args)
        {
            IVssImplementation vssImplementation = VssUtils.LoadImplementation();

            using (IVssBackupComponents backup = vssImplementation.CreateVssBackupComponents())
            {
                backup.InitializeForBackup(null);

                if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                {
                    // This does not work on Windows XP, since the only context supported
                    // on Windows XP is VssSnapshotContext.Backup which is the default.
                    backup.SetContext(VssSnapshotContext.All);
                }

                foreach (VssSnapshotProperties prop in backup.QuerySnapshots())
                {
                    Console.WriteLine("Snapshot ID: {0:B}", prop.SnapshotId);
                    Console.WriteLine("Snapshot Set ID: {0:B}", prop.SnapshotSetId);
                    Console.WriteLine("Original Volume Name: {0}", prop.OriginalVolumeName);
                    Console.WriteLine();
                }
            }
        }
示例#16
0
        /// <summary>
        /// Constructs a new backup snapshot, using all the required disks
        /// </summary>
        /// <param name="sourcepaths">The folders that are about to be backed up</param>
        /// <param name="options">A set of commandline options</param>
        public WindowsSnapshot(string[] sourcepaths, Dictionary <string, string> options)
        {
            try
            {
                //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC
                string             alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss");
                string             alphadll = System.IO.Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
                IVssImplementation vss      = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");

                List <Guid> excludedWriters = new List <Guid>();
                if (options.ContainsKey("vss-exclude-writers"))
                {
                    foreach (string s in options["vss-exclude-writers"].Split(';'))
                    {
                        if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0)
                        {
                            excludedWriters.Add(new Guid(s));
                        }
                    }
                }

                //Check if we should map any drives
                bool useSubst = Utility.Utility.ParseBoolOption(options, "vss-use-mapping");

                //Prepare the backup
                m_backup = vss.CreateVssBackupComponents();
                m_backup.InitializeForBackup(null);

                if (excludedWriters.Count > 0)
                {
                    m_backup.DisableWriterClasses(excludedWriters.ToArray());
                }

                m_backup.StartSnapshotSet();

                m_sourcepaths = new string[sourcepaths.Length];

                for (int i = 0; i < m_sourcepaths.Length; i++)
                {
                    m_sourcepaths[i] = System.IO.Directory.Exists(sourcepaths[i]) ? Utility.Utility.AppendDirSeparator(sourcepaths[i]) : sourcepaths[i];
                }

                try
                {
                    //Gather information on all Vss writers
                    m_backup.GatherWriterMetadata();
                    m_backup.FreeWriterMetadata();
                }
                catch
                {
                    try { m_backup.FreeWriterMetadata(); }
                    catch { }

                    throw;
                }

                //Figure out which volumes are in the set
                m_volumes = new Dictionary <string, Guid>(StringComparer.InvariantCultureIgnoreCase);
                foreach (string s in m_sourcepaths)
                {
                    string drive = Alphaleonis.Win32.Filesystem.Path.GetPathRoot(s);
                    if (!m_volumes.ContainsKey(drive))
                    {
                        if (!m_backup.IsVolumeSupported(drive))
                        {
                            throw new VssVolumeNotSupportedException(drive);
                        }

                        m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive));
                    }
                }

                //Signal that we want to do a backup
                m_backup.SetBackupState(false, true, VssBackupType.Full, false);

                //Make all writers aware that we are going to do the backup
                m_backup.PrepareForBackup();

                //Create the shadow volumes
                m_backup.DoSnapshotSet();

                //Make a little lookup table for faster translation
                m_volumeMap = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);
                foreach (KeyValuePair <string, Guid> kvp in m_volumes)
                {
                    m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject);
                }

                //If we should map the drives, we do that now and update the volumeMap
                if (useSubst)
                {
                    m_mappedDrives = new List <DefineDosDevice>();
                    foreach (string k in new List <string>(m_volumeMap.Keys))
                    {
                        try
                        {
                            DefineDosDevice d;
                            m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k]));
                            m_volumeMap[k]       = Utility.Utility.AppendDirSeparator(d.Drive);
                        }
                        catch { }
                    }
                }
            }
            catch
            {
                //In case we fail in the constructor, we do not want a snapshot to be active
                try { Dispose(); }
                catch { }

                throw;
            }
        }
示例#17
0
        private void BackupSubset(IDictionary <string, string> vmNamesMapSubset, Options options)
        {
            IVssImplementation vssImpl = VssUtils.LoadImplementation();

            using (IVssBackupComponents vss = vssImpl.CreateVssBackupComponents())
            {
                RaiseEvent(EventAction.InitializingVSS, null, null);

                vss.InitializeForBackup(null);
                vss.SetBackupState(true, true, VssBackupType.Full, false);
                vss.SetContext(VssSnapshotContext.Backup);

                // Add Hyper-V writer
                Guid hyperVwriterGuid = new Guid("66841cd4-6ded-4f4b-8f17-fd23f8ddc3de");
                vss.EnableWriterClasses(new Guid[] { hyperVwriterGuid });

                vss.GatherWriterMetadata();

                IList <IVssWMComponent> components = new List <IVssWMComponent>();
                // key: volumePath, value: volumeName. These values are equivalent on a standard volume, but differ in the CSV case
                IDictionary <string, string> volumeMap = new Dictionary <string, string>();

                var wm = vss.WriterMetadata.Where((o) => o.WriterId.Equals(hyperVwriterGuid)).FirstOrDefault();
                foreach (var component in wm.Components)
                {
                    if (vmNamesMapSubset.ContainsKey(component.ComponentName))
                    {
                        components.Add(component);
                        vss.AddComponent(wm.InstanceId, wm.WriterId, component.Type, component.LogicalPath, component.ComponentName);
                        foreach (var file in component.Files)
                        {
                            string volumeName = null;
                            string volumePath = null;

                            volumePath = Path.GetPathRoot(file.Path).ToUpper();
                            volumeName = volumePath;

                            if (!volumeMap.ContainsKey(volumePath))
                            {
                                volumeMap.Add(volumePath, volumeName);
                            }
                        }
                    }
                }

                if (components.Count > 0)
                {
                    Guid vssSet = vss.StartSnapshotSet();

                    // Key: volumeName, value: snapshotGuid
                    IDictionary <string, Guid> snapshots = new Dictionary <string, Guid>();

                    foreach (var volumeName in volumeMap.Values)
                    {
                        snapshots.Add(volumeName, vss.AddToSnapshotSet(volumeName, Guid.Empty));
                    }

                    vss.PrepareForBackup();

                    RaiseEvent(EventAction.StartingSnaphotSet, components, volumeMap);
                    vss.DoSnapshotSet();
                    RaiseEvent(EventAction.SnapshotSetDone, components, volumeMap);

                    // key: volumeName, value: snapshotVolumePath
                    IDictionary <string, string> snapshotVolumeMap = new Dictionary <string, string>();

                    foreach (var kv in snapshots)
                    {
                        snapshotVolumeMap.Add(kv.Key, vss.GetSnapshotProperties(kv.Value).SnapshotDeviceObject);
                    }

                    BackupFiles(components, volumeMap, snapshotVolumeMap, vmNamesMapSubset, options);

                    foreach (var component in components)
                    {
                        vss.SetBackupSucceeded(wm.InstanceId, wm.WriterId, component.Type, component.LogicalPath, component.ComponentName, true);
                    }

                    vss.BackupComplete();

                    RaiseEvent(EventAction.DeletingSnapshotSet, components, volumeMap);
                    vss.DeleteSnapshotSet(vssSet, true);
                }
            }
        }
        /// <summary>
        /// Constructs a new backup snapshot, using all the required disks
        /// </summary>
        /// <param name="sourcepaths">The folders that are about to be backed up</param>
        /// <param name="options">A set of commandline options</param>
        public WindowsSnapshot(string[] sourcepaths, Dictionary <string, string> options)
        {
            try
            {
                //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC
                string             alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss");
                string             alphadll = System.IO.Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
                IVssImplementation vss      = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");

                var excludedWriters = new Guid[0];
                if (options.ContainsKey("vss-exclude-writers"))
                {
                    excludedWriters = options["vss-exclude-writers"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).Select(x => new Guid(x)).ToArray();
                }

                //Check if we should map any drives
                bool useSubst = Utility.Utility.ParseBoolOption(options, "vss-use-mapping");

                //Prepare the backup
                m_backup = vss.CreateVssBackupComponents();
                m_backup.InitializeForBackup(null);
                m_backup.SetContext(VssSnapshotContext.Backup);
                m_backup.SetBackupState(false, true, VssBackupType.Full, false);

                if (excludedWriters.Length > 0)
                {
                    m_backup.DisableWriterClasses(excludedWriters.ToArray());
                }

                m_sourcepaths = sourcepaths.Select(x => Directory.Exists(x) ? Utility.Utility.AppendDirSeparator(x) : x).ToList();

                List <string> hypervPaths;

                try
                {
                    m_backup.GatherWriterMetadata();

                    hypervPaths = PrepareHyperVBackup(options, m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(HyperVWriterGuid)));
                }
                finally
                {
                    m_backup.FreeWriterMetadata();
                }

                if (hypervPaths != null)
                {
                    m_sourcepaths.AddRange(hypervPaths);
                }

                //Sanity check for duplicate files/folders
                var pathDuplicates = m_sourcepaths.GroupBy(x => x, Utility.Utility.ClientFilenameStringComparer)
                                     .Where(g => g.Count() > 1).Select(y => y.Key).ToList();

                foreach (var pathDuplicate in pathDuplicates)
                {
                    Logging.Log.WriteMessage(string.Format("Removing duplicate source: {0}", pathDuplicate), Logging.LogMessageType.Information);
                }

                if (pathDuplicates.Count > 0)
                {
                    m_sourcepaths = m_sourcepaths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList();
                }

                //Sanity check for multiple inclusions of the same files/folders
                var pathIncludedPaths = m_sourcepaths.Where(x => m_sourcepaths.Where(y => y != x).Any(z => x.StartsWith(z, Utility.Utility.ClientFilenameStringComparision))).ToList();

                foreach (var pathIncluded in pathIncludedPaths)
                {
                    Logging.Log.WriteMessage(string.Format("Removing already included source: {0}", pathIncluded), Logging.LogMessageType.Information);
                }

                if (pathIncludedPaths.Count > 0)
                {
                    m_sourcepaths = m_sourcepaths.Except(pathIncludedPaths, Utility.Utility.ClientFilenameStringComparer).ToList();
                }

                m_backup.StartSnapshotSet();

                //Figure out which volumes are in the set
                m_volumes = new Dictionary <string, Guid>(StringComparer.InvariantCultureIgnoreCase);
                foreach (string s in m_sourcepaths)
                {
                    string drive = Alphaleonis.Win32.Filesystem.Path.GetPathRoot(s);
                    if (!m_volumes.ContainsKey(drive))
                    {
                        if (!m_backup.IsVolumeSupported(drive))
                        {
                            throw new VssVolumeNotSupportedException(drive);
                        }

                        m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive));
                    }
                }

                //Make all writers aware that we are going to do the backup
                m_backup.PrepareForBackup();

                //Create the shadow volumes
                m_backup.DoSnapshotSet();

                //Make a little lookup table for faster translation
                m_volumeMap = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);
                foreach (KeyValuePair <string, Guid> kvp in m_volumes)
                {
                    m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject);
                }

                //If we should map the drives, we do that now and update the volumeMap
                if (useSubst)
                {
                    m_mappedDrives = new List <DefineDosDevice>();
                    foreach (string k in new List <string>(m_volumeMap.Keys))
                    {
                        try
                        {
                            DefineDosDevice d;
                            m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k]));
                            m_volumeMap[k]       = Utility.Utility.AppendDirSeparator(d.Drive);
                        }
                        catch { }
                    }
                }
            }
            catch
            {
                //In case we fail in the constructor, we do not want a snapshot to be active
                try { Dispose(); }
                catch { }

                throw;
            }
        }
示例#19
0
        private static void Zip()
        {
            Log2 vssLog = new Log2(nameof(AddonsBackup) + " - VSS Service");
            // get free drive letter
            string driveLetter = new string[] { "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:" }.FirstOrDefault(l => !DriveInfo.GetDrives().Select(m => m.RootDirectory.Name).Contains(l));

            if (driveLetter == default(string))
            {
                throw new IOException("Can't find free drive letter!");
            }
            vssLog.Info($"Free drive letter: {driveLetter}");
            // making VSS snapshot
            IVssImplementation   vssImplementation = VssUtils.LoadImplementation();
            IVssBackupComponents backupComponents  = vssImplementation.CreateVssBackupComponents();

            backupComponents.InitializeForBackup(null);
            vssLog.Info("VssBackupComponents is initialized");
            Guid backupGuid1 = Guid.Empty;

            try
            {
                backupComponents.GatherWriterMetadata();
                backupComponents.SetContext(VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease);
                backupComponents.SetBackupState(false, true, VssBackupType.Full, false);
                vssLog.Info("VssBackupComponents is set up");
                backupComponents.StartSnapshotSet();
                backupGuid1 = backupComponents.AddToSnapshotSet(new DirectoryInfo(_settings.WoWDirectory).Root.Name, Guid.Empty);
                backupComponents.PrepareForBackup();
                backupComponents.DoSnapshotSet();
                vssLog.Info("Snapshot is taken");
                backupComponents.ExposeSnapshot(backupGuid1, null, VssVolumeSnapshotAttributes.ExposedLocally, driveLetter);
                // zipping
                string zipPath = $"{_settings.WoWAddonsBackupPath}\\AddonsBackup_{DateTime.UtcNow:yyyyMMdd_HHmmss}.zip";
                log.Info("Zipping to file: " + zipPath);
                using (ZipFile zip = new ZipFile(zipPath, Encoding.UTF8))
                {
                    zip.CompressionLevel = (CompressionLevel)_settings.WoWAddonsBackupCompressionLevel;
                    foreach (string dirName in FoldersToArchive)
                    {
                        zip.AddDirectory(_settings.WoWDirectory.Replace(new DirectoryInfo(_settings.WoWDirectory).Root.Name, $"{driveLetter}\\") + "\\" + dirName, "\\" + dirName);
                    }
                    zip.SaveProgress += AddonsBackup_SaveProgress;
                    var processPriority = Process.GetCurrentProcess().PriorityClass;
                    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
                    zip.Save();
                    Process.GetCurrentProcess().PriorityClass = processPriority;
                    zip.SaveProgress -= AddonsBackup_SaveProgress;
                }
            }
            finally
            {
                VssSnapshotProperties existingSnapshot = backupComponents.QuerySnapshots().FirstOrDefault(l => l.SnapshotId == backupGuid1);
                if (existingSnapshot == default(VssSnapshotProperties))
                {
                    vssLog.Error($"Can't delete snapshot {backupGuid1}");
                }
                else
                {
                    backupComponents.DeleteSnapshot(existingSnapshot.SnapshotId, true);
                    backupComponents.Dispose();
                    vssLog.Info($"Snapshot is deleted ({existingSnapshot.SnapshotId})");
                }
                GC.Collect();
            }
        }
        /// <summary>
        /// Makes a recursive snapshot of the directory as it is.
        /// </summary>
        /// <param name="baseDirectory">The directory to start in.</param>
        /// <returns>A file system snapshot</returns>
        public static SnapshotFilesystem MakeFsSnapshot(System.IO.DirectoryInfo baseDirectory)
        {
            DirectoryInfo baseDir = new DirectoryInfo(baseDirectory.FullName);

            if (!baseDir.Exists)
            {
                throw new ArgumentException("Base directory doesn't exist");
            }

            SnapshotFilesystem res = new SnapshotFilesystem();

            if (!baseDir.FullName.EndsWith(Path.DirectorySeparatorChar) && !baseDir.FullName.EndsWith(Path.AltDirectorySeparatorChar))
            {
                // Add ending slash to get a uniform output
                baseDir = new DirectoryInfo(baseDir.FullName + Path.DirectorySeparatorChar);
            }

            res.BasePath = baseDir.FullName;
            res.Items    = new LinkedList <SnapshotFilesystemItem>();

            // Make VSS
            // Sequence of calls: http://us.generation-nt.com/answer/volume-shadow-copy-backupcomplete-vss-e-bad-state-help-29094302.html
            IVssImplementation   vssImplementation = VssUtils.LoadImplementation();
            IVssBackupComponents backupComponents  = vssImplementation.CreateVssBackupComponents();

            backupComponents.InitializeForBackup(null);
            backupComponents.SetContext(VssSnapshotContext.Backup);

            backupComponents.SetBackupState(false, false, VssBackupType.Copy, false);
            backupComponents.GatherWriterMetadata();

            try
            {
                Guid snapshotSetGuid  = backupComponents.StartSnapshotSet();
                Guid backupVolumeGuid = backupComponents.AddToSnapshotSet(baseDir.Root.FullName);

                backupComponents.PrepareForBackup();
                backupComponents.DoSnapshotSet();

                VssSnapshotProperties properties = backupComponents.GetSnapshotProperties(backupVolumeGuid);

                DirectoryInfo shadowCopyBase = new DirectoryInfo(Path.Combine(properties.SnapshotDeviceObject, Path.GetDirectoryNameWithoutRoot(baseDir.FullName)));

                if (!shadowCopyBase.FullName.EndsWith(Path.DirectorySeparatorChar) && !shadowCopyBase.FullName.EndsWith(Path.AltDirectorySeparatorChar))
                {
                    // Add ending slash to get a uniform output
                    shadowCopyBase = new DirectoryInfo(shadowCopyBase.FullName + Path.DirectorySeparatorChar);
                }

                // Do stuff
                DoFsSnapshot(shadowCopyBase, shadowCopyBase, res.Items);

                // Delete snapshot
                backupComponents.BackupComplete();
                backupComponents.DeleteSnapshotSet(snapshotSetGuid, false);
            }
            catch (Exception)
            {
                backupComponents.AbortBackup();
            }

            //DoFsSnapshot(baseDirectory, baseDirectory, res.Items);

            return(res);
        }
示例#21
0
文件: Program.cs 项目: zhaokk/bhv
        /// <summary>
        /// This is only first test of using AlphaVSS project.
        /// Please make sure you read thoroughly and understand the code's comments and adapt it to your system and needs.
        /// We are using constant links for "source files to copy" and for the "destination folder".
        /// In any dynamic application you should get those values from the user.
        ///
        /// building your project:
        /// -----------------------
        /// 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 install the package)
        /// 3. Go over the Code's comment and understand it!!! After you are ready you can use it.
        /// 4. add "using Alphaleonis.Win32.Vss;" & "using System.IO;"
        /// </summary>
        /// <param name="args"></param>
        public static void copy(string destination)
        {
            // Getting information on the files to copy (This is not part of the VSS action)
            string   userName     = Environment.UserName;
            string   baseAddress  = @"C:\Users\{0}\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat";
            string   directory    = string.Format(baseAddress, userName);
            String   _Source1     = directory;
            String   _Destination = destination;
            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!
             * /* please more information at http://technet.microsoft.com/en-us/library/ee923636.aspx
             * /***********************************/

            // 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, "S:");

            // 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, @"S:\");

            if (File.Exists(sVSSFile1))
            {
                System.IO.File.Copy(sVSSFile1, _Destination + @"\" + System.IO.Path.GetFileName(_Source1), true);
            }


            // VSS step 9: Delete the snapshot (using the Exposed Snapshot name)
            foreach (VssSnapshotProperties prop in _backup.QuerySnapshots())
            {
                if (prop.ExposedName == @"S:\")
                {
                    Console.WriteLine("prop.ExposedNam Found!");
                    _backup.DeleteSnapshot(prop.SnapshotId, true);
                }
            }

            _backup = null;
        }
        public void Backup(Tuple <string, string> paths)
        {
            String               _Source1           = paths.Item1;
            String               _Destination       = paths.Item2;
            FileInfo             MyFileInfo         = new FileInfo(_Source1);
            String               _Volume            = MyFileInfo.Directory.Root.Name;
            IVssImplementation   _vssImplementation = VssUtils.LoadImplementation();
            IVssBackupComponents _backup            = _vssImplementation.CreateVssBackupComponents();

            _backup.InitializeForBackup(null);
            _backup.GatherWriterMetadata();
            _backup.SetContext(VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease);
            _backup.SetBackupState(false, true, Alphaleonis.Win32.Vss.VssBackupType.Full, false);
            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();
            // GET drive labels in use
            var d_name = " ";
            var d_nam  = " ";

            DriveInfo[] allDrives = DriveInfo.GetDrives();
            foreach (DriveInfo d in allDrives)
            {
                if (d.Name != @"A:\")
                {
                    d_name = @"A:\";
                    d_nam  = @"A:";
                }
                else if (d.Name != @"B:\")
                {
                    d_name = @"B:\";
                    d_nam  = @"A:";
                }
                else if (d.Name != @"Z:\")
                {
                    d_name = @"Z:\";
                    d_nam  = @"Z:";
                }
            }
            _backup.ExposeSnapshot(MyGuid02, null, VssVolumeSnapshotAttributes.ExposedLocally, d_nam);
            String sVSSFile1 = _Source1.Replace(_Volume, d_name);

            if (File.Exists(sVSSFile1))
            {
                System.IO.File.Copy(sVSSFile1, _Destination + @"\" + System.IO.Path.GetFileName(_Source1), true);
            }
            foreach (VssSnapshotProperties prop in _backup.QuerySnapshots())
            {
                if (prop.ExposedName == d_name)
                {
                    Console.WriteLine("prop.ExposedNam Found!");
                    _backup.DeleteSnapshot(prop.SnapshotId, true);
                }
            }
            _backup = null;
            return;
        }
示例#23
0
        public List <ISnapshot> ListSpecialObjects()
        {
            List <ISnapshot>   alreadyExisting   = new List <ISnapshot>();
            IVssImplementation vssImplementation = VssUtils.LoadImplementation();

            using (IVssBackupComponents backup = vssImplementation.CreateVssBackupComponents()){
                backup.InitializeForBackup(null);
                using (IVssAsync async = backup.GatherWriterMetadata()){
                    async.Wait();
                    async.Dispose();
                }

                if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                {
                    // The only context supported on Windows XP is VssSnapshotContext.All
                    //backup.SetContext(VssSnapshotContext.Backup);
                    backup.SetContext(VssSnapshotContext.AppRollback | VssSnapshotContext.All);
                }
                //backup.SetBackupState(false,  true, VssBackupType.Full, false);
                //Guid snapID = backup.StartSnapshotSet();
                //backup.AddToSnapshotSet(@"C:\");
                foreach (IVssExamineWriterMetadata writer in backup.WriterMetadata)
                {
                    VSSSnapshot s = new VSSSnapshot();
                    s.Path       = writer.WriterName;
                    s.Type       = (writer.Source == VssSourceType.TransactedDB || writer.Source == VssSourceType.NonTransactedDB)? "VSSDB" : "VSSWriter";
                    s.Version    = writer.Version.Major + "." + writer.Version.Minor + "." + writer.Version.MajorRevision + "." + writer.Version.MinorRevision + writer.Version.Revision;
                    s.MountPoint = writer.WriterName;
                    foreach (IVssWMComponent cmp in writer.Components)
                    {
                        VSSSnapshot childS = new VSSSnapshot();
                        childS.Path = cmp.ComponentName;
                        childS.Icon = cmp.GetIcon();
                        childS.Type = (cmp.Type == VssComponentType.Database)? "VSSDB" : "VSSFileGroup";
                        if (!cmp.Selectable)
                        {
                            childS.Type = "spoDisabled";
                        }
                        childS.MountPoint = cmp.LogicalPath;
                        childS.Disabled   = true;
                        if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                        {
                            foreach (VssWMDependency dep in cmp.Dependencies)
                            {
                                Logger.Append(Severity.INFO, "TODO: vss component " + cmp.ComponentName + " has dependancy on " + dep.ComponentName);
                            }
                        }
                        if (cmp.Selectable)
                        {
                            childS.Disabled = false;
                        }
                        s.AddChildComponent(childS);
                    }
                    alreadyExisting.Add(s);
                }
                //backup.QueryProviders
                foreach (IVssWriterComponents wc in   backup.WriterComponents)
                {
                    foreach (IVssComponent c in wc.Components)
                    {
                        VSSSnapshot s = new VSSSnapshot();
                        s.Path = c.ComponentName;
                        s.Type = c.ComponentType.ToString();
                        alreadyExisting.Add(s);
                    }
                }
            }
            return(alreadyExisting);
        }
示例#24
0
        public ISnapshot[] CreateVolumeSnapShot(List <FileSystem> volumes, string[] spoPaths, SnapshotSupportedLevel level)
        {
            using (new Alphaleonis.Win32.Security.PrivilegeEnabler(Privilege.Backup, Privilege.Restore)){
                //PrivilegesManager pm = new PrivilegesManager();
                //pm.Grant();
                VssBackupType vssLevel = VssBackupType.Full;
                if (level == SnapshotSupportedLevel.Full)
                {
                    vssLevel = VssBackupType.Full;
                }
                else if (level == SnapshotSupportedLevel.Incremental)
                {
                    vssLevel = VssBackupType.Incremental;
                }
                else if (level == SnapshotSupportedLevel.Differential)
                {
                    vssLevel = VssBackupType.Differential;
                }
                else if (level == SnapshotSupportedLevel.TransactionLog)
                {
                    vssLevel = VssBackupType.Log;
                }
                ArrayList snapshots = new ArrayList();
                Metadata = new SPOMetadata();
                bool snapshotSuccedeed = false;
                try{
                    IVssImplementation vss = VssUtils.LoadImplementation();
                    backup = vss.CreateVssBackupComponents();
                    Logger.Append(Severity.DEBUG, "0/6 Initializing Snapshot (" + ((spoPaths == null)? "NON-component mode" : "component mode") + ", level " + level + ")");
                    backup.InitializeForBackup(null);
                    if (spoPaths == null)            // component-less snapshot set
                    {
                        backup.SetBackupState(false, true, VssBackupType.Full, false);
                    }
                    else
                    {
                        backup.SetBackupState(true, true, vssLevel, (vssLevel == VssBackupType.Full)?false:true);
                    }
                    if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                    {
                        // The only context supported on Windows XP is VssSnapshotContext.Backup
                        backup.SetContext(VssSnapshotContext.AppRollback /*|VssSnapshotContext.All*/);
                    }
                    Logger.Append(Severity.DEBUG, "1/6 Gathering writers metadata and status");
                    using (IVssAsync async = backup.GatherWriterMetadata()){
                        async.Wait();
                        async.Dispose();
                    }
                    // gather writers status before adding backup set components
                    using (IVssAsync async = backup.GatherWriterStatus()){
                        async.Wait();
                        async.Dispose();
                    }
                    Logger.Append(Severity.DEBUG, "2/6 Adding writers and components");
                    // Now we add the components (vss writers, writer paths/params) of this snapshot set
                    if (spoPaths != null)
                    {
                        foreach (IVssExamineWriterMetadata writer in backup.WriterMetadata)
                        {
                            foreach (string spo in spoPaths)
                            {
                                //Logger.Append (Severity.TRIVIA, "Searching writer and/or component matching "+spo);
                                int index = spo.IndexOf(writer.WriterName);
                                if (index < 0 && spo != "*")
                                {
                                    continue;
                                }
                                bool found = false;
                                Logger.Append(Severity.TRIVIA, "Found matching writer " + writer.WriterName + ", instance name=" + writer.InstanceName);
                                // First we check that the writer's status is OK, else we don't add it to avoid failure of complete snapshot if it's not
                                bool writerOk = false;
                                foreach (VssWriterStatusInfo status in backup.WriterStatus)
                                {
                                    if (status.Name == writer.WriterName)
                                    {
                                        Logger.Append(Severity.TRIVIA, "Checking required writer " + status.Name
                                                      + ", status=" + status.State.ToString() + ", error state=" + status.Failure.ToString());
                                        if (status.State == VssWriterState.Stable && status.Failure == VssError.Success)                                // if we get there it means that we are ready to add the wanted component to VSS set
                                        {
                                            writerOk = true;
                                        }
                                        else
                                        {
                                            Logger.Append(Severity.ERROR, "Cannot add writer " + status.Name + " to snapshot set,"
                                                          + " status=" + status.State.ToString() + ". Backup data  managed by this writer may not be consistent");
                                            if (LogEvent != null)
                                            {
                                                LogEvent(this, new LogEventArgs(820, Severity.WARNING, status.Name + ", Status=" + status.State.ToString() + ", Failure=" + status.Failure.ToString()));
                                            }
                                        }
                                    }
                                }
                                if (!writerOk)
                                {
                                    if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                                    {
                                        backup.DisableWriterClasses(new Guid[] { writer.WriterId });
                                    }
                                    continue;
                                }
                                bool addAllComponents = false;
                                if (spo.Length == index + writer.WriterName.Length || spo == "*" || spo == "" + writer.WriterName + @"\*")
                                {
                                    addAllComponents = true;
                                }
                                foreach (IVssWMComponent component in writer.Components)
                                {
                                    found = false;
                                    //Console.WriteLine("createvolsnapshot : current component is :"+component.LogicalPath+@"\"+component.ComponentName);
                                    if ((!addAllComponents) && spo.IndexOf(component.LogicalPath + @"\" + component.ComponentName) < 0)
                                    {
                                        continue;
                                    }
                                    //Logger.Append (Severity.TRIVIA, "Asked to recursively select all '"+writer.WriterName+"' writer's components");
                                    if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                                    {
                                        foreach (VssWMDependency dep in  component.Dependencies)
                                        {
                                            Logger.Append(Severity.TRIVIA, "Component " + component.ComponentName + " depends on component " + dep.ComponentName);
                                        }
                                    }
                                    if (component.Selectable)
                                    {
                                        backup.AddComponent(writer.InstanceId, writer.WriterId, component.Type, component.LogicalPath, component.ComponentName);
                                    }
                                    Logger.Append(Severity.INFO, "Added writer '" + writer.WriterName + "' component " + component.ComponentName);
                                    found = true;

                                    // Second we need to find every drive containing files necessary for writer's backup
                                    // and add them to drives list, in case they weren't explicitely selected as part of backuppaths
                                    List <VssWMFileDescription> componentFiles = new List <VssWMFileDescription>();
                                    componentFiles.AddRange(component.Files);
                                    componentFiles.AddRange(component.DatabaseFiles);
                                    componentFiles.AddRange(component.DatabaseLogFiles);
                                    foreach (VssWMFileDescription file in componentFiles)
                                    {
                                        if (string.IsNullOrEmpty(file.Path))
                                        {
                                            continue;
                                        }
                                        //Console.WriteLine ("component file path="+file.Path+", alt backuplocation="+file.AlternateLocation
                                        //		+", backuptypemask="+file.BackupTypeMask.ToString()+", spec="+file.FileSpecification+", recursive="+file.IsRecursive);
                                        // TODO : Reuse GetInvolvedDrives (put it into VolumeManager class)
                                        string drive = file.Path.Substring(0, 3).ToUpper();
                                        if (drive.Contains(":") && drive.Contains("\\"))
                                        {
                                            var searchedVol = from FileSystem vol in volumes
                                                              where vol.MountPoint.Contains(drive)
                                                              select vol;
                                            //if(!volumes.Contains(drive)){
                                            if (searchedVol == null)
                                            {
                                                Logger.Append(Severity.INFO, "Select VSS component " + component.LogicalPath
                                                              + @"\" + component.ComponentName + " requires snapshotting of drive " + drive + ", adding it to the list.");
                                                volumes.Add(searchedVol.First());
                                            }
                                            break;
                                        }
                                    }

                                    //Logger.Append(Severity.TRIVIA, "Added writer/component "+spo);
                                    //break;
                                }
                                //metadata.Metadata.Add(writer.SaveAsXml());
                                Metadata.Metadata.Add(writer.WriterName, writer.SaveAsXml());
                                if (found == false)
                                {
                                    Logger.Append(Severity.WARNING, "Could not find VSS component " + spo + " which was part of backup paths");
                                }
                            }
                        }
                    }
                    Logger.Append(Severity.DEBUG, "3/6 Preparing Snapshot ");
                    //backup.SetBackupState(false,  true, VssBackupType.Full, false);
                    Guid snapID = backup.StartSnapshotSet();
                    //Guid volID = new Guid();
                    foreach (FileSystem volume in volumes)
                    {
                        VSSSnapshot snapshot = new VSSSnapshot();
                        snapshot.Type = this.Name;
                        Logger.Append(Severity.DEBUG, "Preparing Snapshot of " + volume.MountPoint);
                        if (volume.MountPoint != null && backup.IsVolumeSupported(volume.MountPoint))
                        {
                            snapshot.Id = backup.AddToSnapshotSet(volume.MountPoint);

                            snapshot.Path = volume.MountPoint;
                        }
                        else                  // return the fake provider to get at least a degraded backup, better than nothing
                        {
                            Logger.Append(Severity.WARNING, "Volume '" + volume.MountPoint + "' is not snapshottable (or null). Backup will be done without snapshot, risks of data inconsistancy.");
                            ISnapshotProvider fakeSnapProvider = SnapshotProvider.GetProvider("NONE");
                            List <FileSystem> fakeList         = new List <FileSystem>();
                            fakeList.Add(volume);
                            snapshot = (VSSSnapshot)fakeSnapProvider.CreateVolumeSnapShot(fakeList, null, SnapshotSupportedLevel.Full)[0];
                        }
                        if (snapshot.Id == System.Guid.Empty)
                        {
                            Logger.Append(Severity.ERROR, "Unable to add drive " + volume.MountPoint + " to snapshot set (null guid)");
                        }
                        else
                        {
                            Logger.Append(Severity.TRIVIA, "Drive " + volume.MountPoint + " will be snapshotted to " + snapshot.Id);
                        }
                        snapshots.Add(snapshot);
                    }
                    Logger.Append(Severity.DEBUG, "4/6 Calling Prepare...");
                    using (IVssAsync async = backup.PrepareForBackup()){
                        async.Wait();
                        async.Dispose();
                    }
                    Logger.Append(Severity.DEBUG, "5/6 Snapshotting volumes");
                    using (IVssAsync async = backup.DoSnapshotSet()){
                        async.Wait();
                        async.Dispose();
                    }
                    //if(OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003))
                    foreach (IVssExamineWriterMetadata w in backup.WriterMetadata)
                    {
                        foreach (IVssWMComponent comp in w.Components)
                        {
                            try{
                                backup.SetBackupSucceeded(w.InstanceId, w.WriterId, comp.Type, comp.LogicalPath, comp.ComponentName, true);
                                Logger.Append(Severity.TRIVIA, "Component " + comp.ComponentName + " has been notified about backup success.");
                            }
                            catch (Exception) {
                                //Logger.Append (Severity.WARNING, "Could not notify component "+comp.ComponentName+" about backup completion : "+se.Message);
                            }
                        }
                    }
                    //Node.Misc.VSSObjectHandle.StoreObject(backup);
                    try{
                        //on XP backupcomplete consider that we have done with the snapshot and releases it.
                        //if(OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003)){
                        backup.BackupComplete();

                        Metadata.Metadata.Add("_bcd_", backup.SaveAsXml());
                        //}
                    }catch (Exception bce) {
                        Logger.Append(Severity.WARNING, "Error calling VSS BackupComplete() : " + bce.Message);
                    }

                    using (IVssAsync async = backup.GatherWriterStatus()){
                        async.Wait();
                        async.Dispose();
                    }

                    Logger.Append(Severity.DEBUG, "6/6 Successfully shapshotted volume(s) ");

                    foreach (ISnapshot sn in snapshots)
                    {
                        if (sn.Id == Guid.Empty)
                        {
                            continue;
                        }
                        sn.MountPoint = backup.GetSnapshotProperties(sn.Id).SnapshotDeviceObject;
                        sn.TimeStamp  = Utilities.Utils.GetUtcUnixTime(backup.GetSnapshotProperties(sn.Id).CreationTimestamp.ToUniversalTime());

                        /*
                         * DirectoryInfo snapMountPoint = Directory.CreateDirectory( Path.Combine(Utilities.ConfigManager.GetValue("Backups.TempFolder"), "snapshot_"+sn.Id));
                         * Logger.Append(Severity.DEBUG, "Mounting shapshotted volume '"+sn.Name+"' to '"+snapMountPoint.FullName+"'");
                         * backup.ExposeSnapshot(sn.Id, null, VssVolumeSnapshotAttributes.ExposedLocally, snapMountPoint.FullName);
                         * //sn.Path = snapMountPoint.FullName+Path.DirectorySeparatorChar;
                         * //sn.Path = @"\\?\Volume{"+sn.Id+"}"+Path.DirectorySeparatorChar;*/
                    }
                }
                catch (Exception e) {
                    try{
                        //backup.BackupComplete();
                        backup.AbortBackup();
                    }
                    catch (Exception ae) {
                        Logger.Append(Severity.ERROR, "Error trying to cancel VSS snapshot set : " + ae.Message);
                    }

                    // TODO !! report snapshoty failure to hub task
                    Logger.Append(Severity.ERROR, "Error creating snapshot :'" + e.Message + " ---- " + e.StackTrace + "'. Backup will continue without snapshot. Backup of VSS components will fail. !TODO! report that to hub");
                    backup.Dispose();
                    throw new Exception(e.Message);
                }
                finally{
                    // TODO !!! reactivate dispose
                    //backup.Dispose();

                    //pm.Revoke();
                }

                return((ISnapshot[])snapshots.ToArray(typeof(ISnapshot)));
            }
        }
示例#25
0
        //edit 05.04.2017
        public void StartDiffBackup()
        {
            UpdateSosttask(2);
            IVssBackupComponents backup = null;
            string  namedriver          = "";
            Boolean successtask         = true;

            try
            {
                if (DTask.Shadow == 1)
                {
                    string[]    massdrives = { "A:\\", "B:\\", "D:\\", "E:\\", "I:\\", "K:\\", "L:\\", "M:\\", "N:\\", "O:\\", "P:\\" };
                    string      havedriver = "";
                    DriveInfo[] drives     = DriveInfo.GetDrives();
                    foreach (DriveInfo d in drives)
                    {
                        havedriver = havedriver + d.Name;
                    }
                    foreach (string strdriver in massdrives)
                    {
                        if (!havedriver.Contains(strdriver))
                        {
                            namedriver = strdriver;
                        }
                    }

                    FileInfo MyFileInfo = new FileInfo(DTask.Source);
                    String   _Volume    = MyFileInfo.Directory.Root.Name;

                    IVssImplementation _vssImplementation = VssUtils.LoadImplementation();
                    backup = _vssImplementation.CreateVssBackupComponents();
                    backup.InitializeForBackup(null);

                    backup.GatherWriterMetadata();

                    backup.SetContext(VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease);
                    backup.SetBackupState(false, true, Alphaleonis.Win32.Vss.VssBackupType.Full, false);

                    Guid MyGuid01 = backup.StartSnapshotSet();
                    Guid MyGuid02 = backup.AddToSnapshotSet(_Volume, Guid.Empty);

                    backup.PrepareForBackup();
                    backup.DoSnapshotSet();

                    backup.ExposeSnapshot(MyGuid02, null, VssVolumeSnapshotAttributes.ExposedLocally, namedriver.Remove(2, 1));

                    DTask.Source = DTask.Source.Replace(_Volume, namedriver);
                }

                StringWriter SW            = new StringWriter();
                StringWriter Skip_file_log = new StringWriter();
                string       time_today    = DateTime.Now.Date.ToShortDateString();
                ZipFile      zf            = new ZipFile(DTask.Dest + "\\" + DTask.Taskname + "_" + time_today.Replace(".", "-") + "." + DTask.Extension);
                zf.ProvisionalAlternateEncoding = Encoding.GetEncoding("cp866");

                if (DTask.Password != "no")
                {
                    zf.Password = DTask.Password;
                }
                zf.UseZip64WhenSaving      = Zip64Option.AsNecessary;
                zf.ZipErrorAction          = ZipErrorAction.Skip;
                zf.StatusMessageTextWriter = Skip_file_log;

                string[] massexeption;
                string[] separator = { Environment.NewLine };
                massexeption = DTask.Exeption.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                Stack <string> dirs = new Stack <string>(20);
                string         root = DTask.Exeption;

                if (!Directory.Exists(root))
                {
                    throw new ArgumentException();
                }
                dirs.Push(root);


                while (dirs.Count > 0)
                {
                    string   currentDir = dirs.Pop();
                    string[] subDirs;
                    try
                    {
                        subDirs = Directory.GetDirectories(currentDir);
                    }

                    catch (UnauthorizedAccessException e)
                    {
                        SW.WriteLine("Нет доступа к файлу или каталогу: " + currentDir);
                        successtask = false;
                        continue;
                    }
                    catch (DirectoryNotFoundException e)
                    {
                        SW.WriteLine("Не найден файл или каталог: " + currentDir);
                        successtask = false;
                        continue;
                    }
                    catch (PathTooLongException e)
                    {
                        SW.WriteLine("Слишком длинный путь или имя файла: " + currentDir);
                        successtask = false;
                        continue;
                    }


                    string[] files = null;
                    try
                    {
                        files = Directory.GetFiles(currentDir);
                    }

                    catch (UnauthorizedAccessException e)
                    {
                        SW.WriteLine(e.Message);
                        successtask = false;
                        continue;
                    }

                    catch (DirectoryNotFoundException e)
                    {
                        SW.WriteLine(e.Message);
                        successtask = false;
                        continue;
                    }

                    if (DTask.Exeption == "no")
                    {
                        foreach (string file in files)
                        {
                            try
                            {
                                FileInfo fi = new FileInfo(file);
                                if (fi.LastWriteTime > DTask.DateBeginBackup)
                                {
                                    zf.AddFile(file, Path.GetDirectoryName(file).Replace(DTask.Source, string.Empty));
                                }
                            }
                            catch (FileNotFoundException e)
                            {
                                SW.WriteLine("Не найден файл: " + file);
                                successtask = false;
                                continue;
                            }

                            catch (PathTooLongException e)
                            {
                                SW.WriteLine("Слишком длинный путь или имя файла: " + file);
                                successtask = false;
                                continue;
                            }
                        }
                    }
                    else
                    {
                        int excludeflag = 0;
                        foreach (string file in files)
                        {
                            try
                            {
                                excludeflag = 0;
                                foreach (var exep in massexeption)
                                {
                                    if (Path.GetFullPath(file).Contains(exep))
                                    {
                                        excludeflag = 1;
                                        break;
                                    }
                                }
                                if (excludeflag == 0)
                                {
                                    FileInfo fi = new FileInfo(file);
                                    if (fi.LastWriteTime > DTask.DateBeginBackup)
                                    {
                                        zf.AddFile(file, Path.GetDirectoryName(file).Replace(DTask.Source, string.Empty));
                                    }
                                }
                            }
                            catch (FileNotFoundException e)
                            {
                                SW.WriteLine("Не найден файл: " + file);
                                successtask = false;
                                continue;
                            }

                            catch (PathTooLongException e)
                            {
                                SW.WriteLine("Слишком длинный путь или имя файла: " + file);
                                successtask = false;
                                continue;
                            }
                        }
                    }


                    foreach (string str in subDirs)
                    {
                        dirs.Push(str);
                    }
                }



                zf.Save();
                zf.Dispose();
                if (successtask)
                {
                    UpdateSosttask(4);
                }
                else
                {
                    UpdateSosttask(5);
                }


                if (DTask.Shadow == 1)
                {
                    foreach (VssSnapshotProperties prop in backup.QuerySnapshots())
                    {
                        if (prop.ExposedName == namedriver)
                        {
                            backup.DeleteSnapshot(prop.SnapshotId, true);
                        }
                    }
                    backup = null;
                }

                string       strLine;
                int          CountSkip    = 0;
                StringReader stringreader = new StringReader(SW.ToString());
                while (true)
                {
                    strLine = stringreader.ReadLine();
                    if (strLine != null)
                    {
                        CountSkip++;
                        BDAL.OpenConnection();
                        BDAL.AddDiffLog(strLine, CurrentDate, DTask.Idtask, 0);
                        BDAL.CloseConnection();
                    }
                    else
                    {
                        break;
                    }
                }


                string       strLine2;
                StringReader stringreader2 = new StringReader(Skip_file_log.ToString());
                while (true)
                {
                    strLine2 = stringreader2.ReadLine();
                    if (strLine2 != null)
                    {
                        if (strLine2.Contains("Skipping"))
                        {
                            CountSkip++;
                            BDAL.OpenConnection();
                            BDAL.AddDiffLog(strLine2, CurrentDate, DTask.Idtask, 0);
                            BDAL.CloseConnection();
                        }
                    }
                    else
                    {
                        break;
                    }
                }


                if (CountSkip > 0)
                {
                    UpdateSosttask(5);
                }

                string msg = "Завершено успешно";

                BDAL.OpenConnection();
                BDAL.AddDiffLog(msg, CurrentDate, DTask.Idtask, 1);
                BDAL.CloseConnection();
                DeleteDimeLive();


                if (DTask.Ftp == 1)
                {
                    try
                    {
                        UpdateSosttask(2);
                        FtpClient    client = new FtpClient();
                        StreamReader sr     = File.OpenText(AppDomain.CurrentDomain.BaseDirectory + "ftp_sett.ini");
                        client.PassiveMode = true;   //Включаем пассивный режим.
                        int    TimeoutFTP   = 30000; //Таймаут.
                        string FTP_SERVER   = sr.ReadLine();
                        int    FTP_PORT     = Convert.ToInt32(sr.ReadLine());
                        string FTP_USER     = sr.ReadLine();
                        string FTP_PASSWORD = Decrypt(sr.ReadLine(), "OFRna73");
                        string FTP_FOLDER   = sr.ReadLine();


                        client.Connect(TimeoutFTP, FTP_SERVER, FTP_PORT);
                        client.Login(TimeoutFTP, FTP_USER, FTP_PASSWORD);
                        if (FTP_FOLDER != "not_folder")
                        {
                            client.ChangeDirectory(TimeoutFTP, FTP_FOLDER);
                        }
                        client.PutFile(TimeoutFTP, zf.Name.Substring(zf.Name.IndexOf(DTask.Taskname)), zf.Name);
                        sr.Close();
                        client.Disconnect(TimeoutFTP);

                        msg = "Копирование архива на FTP сервер завершено успешно";

                        BDAL.OpenConnection();
                        BDAL.AddDiffLog(msg, CurrentDate, DTask.Idtask, 1);
                        BDAL.CloseConnection();
                        UpdateSosttask(4);
                    }
                    catch (Exception ex)
                    {
                        BDAL.OpenConnection();
                        BDAL.AddDiffLog(ex.ToString(), CurrentDate, DTask.Idtask, 0);
                        BDAL.CloseConnection();
                        UpdateSosttask(3);
                    }
                }
            }
            catch (Exception ex)
            {
                Add_Diff_Log_Error(ex.Message);
                try
                {
                    if (DTask.Shadow == 1)
                    {
                        foreach (VssSnapshotProperties prop in backup.QuerySnapshots())
                        {
                            if (prop.ExposedName == namedriver)
                            {
                                backup.DeleteSnapshot(prop.SnapshotId, true);
                            }
                        }
                        backup = null;
                    }
                }
                catch
                {
                }
            }
        }
        /// <summary>
        /// For all MS SQL databases it enumerate all associated paths using VSS data
        /// </summary>
        /// <returns>A collection of DBs and paths</returns>
        public void QueryDBsInfo()
        {
            if (!IsMSSQLInstalled)
            {
                return;
            }

            m_DBs.Clear();

            //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC
            string             alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss");
            string             alphadll = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
            IVssImplementation vss      = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");

            using (var m_backup = vss.CreateVssBackupComponents())
            {
                m_backup.InitializeForBackup(null);
                m_backup.SetContext(VssSnapshotContext.Backup);
                m_backup.SetBackupState(false, true, VssBackupType.Full, false);
                m_backup.EnableWriterClasses(new Guid[] { MSSQLWriterGuid });

                try
                {
                    m_backup.GatherWriterMetadata();
                    var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(MSSQLWriterGuid));

                    if (writerMetaData == null)
                    {
                        throw new Duplicati.Library.Interface.UserInformationException("Microsoft SQL Server VSS Writer not found - cannot backup SQL databases.", "NoMsSqlVssWriter");
                    }

                    foreach (var component in writerMetaData.Components)
                    {
                        var paths = new List <string>();

                        foreach (var file in component.Files)
                        {
                            if (file.FileSpecification.Contains("*"))
                            {
                                if (Directory.Exists(Utility.Utility.AppendDirSeparator(file.Path)))
                                {
                                    paths.Add(Utility.Utility.AppendDirSeparator(file.Path));
                                }
                            }
                            else
                            {
                                if (File.Exists(Path.Combine(file.Path, file.FileSpecification)))
                                {
                                    paths.Add(Path.Combine(file.Path, file.FileSpecification));
                                }
                            }
                        }

                        m_DBs.Add(new MSSQLDB(component.ComponentName, component.LogicalPath + "\\" + component.ComponentName,
                                              paths.ConvertAll(m => m[0].ToString().ToUpperInvariant() + m.Substring(1)).Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList()));
                    }
                }
                finally
                {
                    m_backup.FreeWriterMetadata();
                }
            }
        }
示例#27
0
            public BackupProcessor(string root)
            {
                log.Info("Creating Backup Component");
                _vss = VssUtils.LoadImplementation();
                _backup = _vss.CreateVssBackupComponents();

                _backup.InitializeForBackup(null);
                _backup.GatherWriterMetadata();
                _backup.SetContext(VssSnapshotContext.Backup);

                _root = root;
                if (!_root.EndsWith("\\")) _root += "\\";

                _volRoot = AlphaFS.Path.GetPathRoot(_root);
                log.DebugFormat("Path actual root is [{0}]",_volRoot);
                if (!_backup.IsVolumeSupported(_volRoot))
                {
                    throw new Exception("Volume îs not supported by the backup API");
                }
            }
示例#28
0
        private VssSnapshotProperties GetVssSnapshotFromTime(DateTime selectedCreationTime)
        {
            Debug.WriteLine(string.Format("Selected creation time: {0}", selectedCreationTime.ToLongTimeString()));

            // Get selected restore point
            SystemRestoreItem selectedSystemRestoreItem = null;

            foreach (SystemRestoreItem sri in systemRestorePoints)
            {
                if (sri.CreationTime.ToLocalTime().CompareTo(selectedCreationTime) == 0)
                {
                    selectedSystemRestoreItem = sri;
                    break;
                }
            }

            // Enumerate snapshots using VSS API
            IVssImplementation vssImplmentation = VssUtils.LoadImplementation();
            ////VssBackupComponents vss = new VssBackupComponents();
            IVssBackupComponents vssBackup = vssImplmentation.CreateVssBackupComponents();

            vssBackup.InitializeForBackup(null);
            vssBackup.SetContext(VssSnapshotContext.All);

            List <VssSnapshotProperties> snapshotHourMatches   = new List <VssSnapshotProperties>();
            List <VssSnapshotProperties> snapshotMinuteMatches = new List <VssSnapshotProperties>();

            foreach (VssSnapshotProperties snapshot in vssBackup.QuerySnapshots())
            {
                DateTime truncatedSelectedRestoreItemTime = TruncateToHour(selectedSystemRestoreItem.CreationTime.ToLocalTime());
                DateTime truncatedSnapshotTime            = TruncateToHour(snapshot.CreationTimestamp);

                if (truncatedSelectedRestoreItemTime.CompareTo(truncatedSnapshotTime) == 0)
                {
                    snapshotHourMatches.Add(snapshot);
                }
            }

            if (snapshotHourMatches.Count == 1)
            {
                Debug.WriteLine(string.Format("Snapshot creation time: {0}", snapshotHourMatches[0].CreationTimestamp.ToLongTimeString()));
                return(snapshotHourMatches[0]);
            }
            else if (snapshotHourMatches.Count > 1)
            {
                foreach (VssSnapshotProperties snapshot in snapshotHourMatches)
                {
                    DateTime truncatedSelectedRestoreItemTime = TruncateToMinute(selectedSystemRestoreItem.CreationTime.ToLocalTime());
                    DateTime truncatedSnapshotTime            = TruncateToMinute(snapshot.CreationTimestamp);

                    if (truncatedSelectedRestoreItemTime.CompareTo(truncatedSnapshotTime) == 0)
                    {
                        snapshotMinuteMatches.Add(snapshot);
                    }
                }

                if (snapshotMinuteMatches.Count == 1)
                {
                    Debug.WriteLine(string.Format("Snapshot creation time: {0}", snapshotMinuteMatches[0].CreationTimestamp.ToLongTimeString()));
                    return(snapshotMinuteMatches[0]);
                }
                else if (snapshotMinuteMatches.Count > 1)
                {
                    Debug.WriteLine(string.Format("Found {0} potential matches", snapshotMinuteMatches.Count.ToString()));

                    // Find closest match
                    foreach (VssSnapshotProperties snapshot in snapshotMinuteMatches)
                    {
                        if (selectedSystemRestoreItem.CreationTime.ToLocalTime().CompareTo(snapshot.CreationTimestamp) < 0)
                        {
                            Debug.WriteLine(string.Format("Snapshot creation time: {0}", snapshot.CreationTimestamp.ToLongTimeString()));
                            return(snapshot);
                        }
                    }
                }
            }

            return(null);
        }