private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { BackupComplete(); if (snapShotSet != Guid.Empty) { backup.DeleteSnapshotSet(snapShotSet, true); snapShotSet = Guid.Empty; } if (backup != null) { backup.Dispose(); backup = null; } } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. disposedValue = true; } }
private void Cleanup() { if (_session._mountPoint != null) { _backup.BackupComplete(); VerifyWriterStatus(); _session._mountPoint = null; } if (_snapshotSetID != Guid.Empty) { // apparently fails on Windows 2008 - the non-persistent shadow copy // should be deleted as soon as _backup is disposed of anyway, // so just try to explicitly delete the snapshot set and ignore any issues try { _backup.DeleteSnapshotSet(_snapshotSetID, forceDelete: true); } catch { } } if (_backup != null) { _backup.Dispose(); } lock (_disposeEventSyncObject) { _disposeEvent.Dispose(); _disposeEvent = null; } }
public void Dispose() { if (backup != null) { backup.Dispose(); } }
public void Dispose() { try { if (_mappedDrives != null) { foreach (var d in _mappedDrives) { d.Dispose(); } _mappedDrives = null; } } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "MappedDriveCleanupError", ex, "Failed during VSS mapped drive unmapping"); } try { _vssBackupComponents?.BackupComplete(); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSTerminateError", ex, "Failed to signal VSS completion"); } try { if (_vssBackupComponents != null) { foreach (var g in _volumes.Values) { try { _vssBackupComponents.DeleteSnapshot(g, false); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteError", ex, "Failed to close VSS snapshot"); } } } } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteCleanError", ex, "Failed during VSS esnapshot closing"); } if (_vssBackupComponents != null) { _vssBackupComponents.Dispose(); _vssBackupComponents = null; } }
protected virtual void Dispose(bool disposing) { if (disposing) { if (_backup != null) { _backup.Dispose(); } } }
public void Dispose(bool ok) { try { Complete(ok); Delete(); } catch { } if (_backup != null) { _backup.Dispose(); _backup = null; } }
/// <summary> /// The disposal of this object involves sending completion notices /// to the writers, removing the shadow copies from the system and /// finally releasing the BackupComponents object. This method must /// be called when this class is no longer used. /// </summary> public void Dispose() { try { Complete(true); } catch { } if (_snap != null) { _snap.Dispose(); _snap = null; } if (_backup != null) { _backup.Dispose(); _backup = null; } }
public void Dispose() { try { Complete(true); } catch { } if (thisSnap != null) { thisSnap.Dispose(); thisSnap = null; } if (thisBackup != null) { thisBackup.Dispose(); thisBackup = null; } }
protected virtual void Dispose(bool disposing) { if (disposing) { if (_snapshot != null) { _snapshot.Dispose(); _snapshot = null; } if (_backup != null) { _backup.Dispose(); } } }
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(); } }
/// <inheritdoc /> protected override void Dispose(bool disposing) { if (disposing) { try { if (m_mappedDrives != null) { foreach (var d in m_mappedDrives) { d.Dispose(); } m_mappedDrives = null; } } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "MappedDriveCleanupError", ex, "Failed during VSS mapped drive unmapping"); } try { m_backup?.BackupComplete(); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSTerminateError", ex, "Failed to signal VSS completion"); } try { if (m_backup != null) { foreach (var g in m_volumes.Values) { try { m_backup.DeleteSnapshot(g, false); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteError", ex, "Failed to close VSS snapshot"); } } } } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSSnapShotDeleteCleanError", ex, "Failed during VSS esnapshot closing"); } if (m_backup != null) { m_backup.Dispose(); m_backup = null; } } base.Dispose(disposing); }
public void SetItems(List <string> spoPaths) { foreach (IVssExamineWriterMetadata writer in backup.WriterMetadata) { foreach (string spo in spoPaths) { try{ Logger.Append(Severity.TRIVIA, "Searching writer and/or component matching " + spo + ", current writer=" + writer.InstanceName); int index = spo.IndexOf(writer.WriterName); if (index < 0 && spo != "*") { continue; } bool found = false; // 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) { if (status.State == VssWriterState.Stable) { // if we get there it means that we are ready to add the wanted component to VSS set writerOk = true; Metadata.Metadata.Add(writer.WriterName, writer.SaveAsXml()); } 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. Restore will be hazardous."); if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003)) { backup.DisableWriterClasses(new Guid[] { writer.WriterId }); } } } } bool addAllComponents = false; if (spo.Length == index + writer.WriterName.Length || spo == "*" || spo == "" + writer.WriterName + @"\*") { addAllComponents = true; } // exclude items indicated by writer foreach (VssWMFileDescription file in writer.ExcludeFiles) { BasePath bp = new BasePath(); bp.Type = "FS"; bp.Path = file.Path; bp.ExcludePolicy.Add(file.FileSpecification); //bp.ExcludedPaths = writer.E bp.Recursive = file.IsRecursive; BasePaths.Add(bp); } 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 + " TODO TODO TODO add it automatically"); } } 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); this.ExplodedComponents.Add(writer.WriterName + @"\" + component.LogicalPath + @"\" + 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); BasePath bp = new BasePath(); bp.Path = file.Path; bp.Type = "FS"; //BasePath.PathType.FS; bp.IncludePolicy.Add(file.FileSpecification); bp.Recursive = file.IsRecursive; BasePaths.Add(bp); } //backup.SetBackupSucceeded(writer.InstanceId, writer.WriterId, component.Type, component.LogicalPath, component.ComponentName, false); //Logger.Append(Severity.TRIVIA, "Added writer/component "+spo); //break; } //metadata.Metadata.Add(writer.SaveAsXml()); // Retrieve Backup Components Document //Metadata.Metadata.Add("bcd", backup.SaveAsXml()); if (found == false) { Logger.Append(Severity.WARNING, "Could not find VSS component " + spo + " which was part of backup paths"); } } catch (Exception e) { Console.WriteLine(" *** SetItems() : error " + e.Message); } } } //backup.BackupComplete(); backup.FreeWriterStatus(); backup.FreeWriterMetadata(); backup.AbortBackup(); backup.Dispose(); }
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))); } }
/// <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() { IVssBackupComponents m_backup = null; var ret = new Dictionary <string, List <string> >(); 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"); 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(); } } finally { try { if (m_backup != null) { m_backup.Dispose(); } } catch { } } return(ret); }