using System; using System.Collections; using System.Collections.Generic; using System.Text; using Interop.VixCOM; using System.IO; namespace Vestris.VMWareLib { /// /// A collection of snapshots at any snapshot level. /// public class VMWareSnapshotCollection : IEnumerable, IDisposable { /// /// Virtual machine handle. /// protected IVM2 _vm = null; /// /// Internal list of snapshots. /// protected List _snapshots = null; private VMWareSnapshot _parent = null; /// /// Snapshot collection constructor. /// /// Virtual machine. /// Snapshot parent. public VMWareSnapshotCollection(IVM2 vm, VMWareSnapshot parent) { _vm = vm; _parent = parent; } /// /// The list of snapshots. /// protected virtual List Snapshots { get { if (_snapshots == null) { _snapshots = new List(); } return _snapshots; } } /// /// Find a snapshot. /// /// Path to a snapshot. /// A snapshot, null if not found. public VMWareSnapshot FindSnapshot(string pathToSnapshot) { string[] paths = pathToSnapshot.Split("\\".ToCharArray(), 2); foreach (VMWareSnapshot snapshot in this) { // last snapshot in the path if (snapshot.DisplayName == paths[0]) { return (paths.Length == 1) ? snapshot : snapshot.ChildSnapshots.FindSnapshot(paths[1]); } } return null; } /// /// Find a snapshot by name. Unlike GetSnapshotByName this function /// doesn't throw an exception when there're two snapshots of the same name, it returns /// the first snapshot found. /// /// Name of a snapshot. /// The first snapshot that matches the name, null if not found. public VMWareSnapshot FindSnapshotByName(string name) { foreach (VMWareSnapshot snapshot in this) { if (snapshot.DisplayName == name) { return snapshot; } VMWareSnapshot childSnapshot = snapshot.ChildSnapshots.FindSnapshotByName(name); if (childSnapshot != null) { return childSnapshot; } } return null; } /// /// Find all snapshots by name. This can return multiple snapshots /// that have the same name. /// /// Name of a snapshot. /// The first snapshot that matches the name, null if not found. public IEnumerable FindSnapshotsByName(string name) { List snapshots = new List(); foreach (VMWareSnapshot snapshot in this) { if (snapshot.DisplayName == name) { snapshots.Add(snapshot); } snapshots.AddRange(snapshot.ChildSnapshots.FindSnapshotsByName(name)); } return snapshots; } /// /// Copy to an array of VMWareSnapshots. /// /// Target array. /// Array index. public void CopyTo(VMWareSnapshot[] array, int arrayIndex) { Snapshots.CopyTo(array, arrayIndex); } /// /// Returns true if this virtual machine has the snapshot specified. /// /// Snapshot. /// True if the virtual machine contains the specified snapshot. public bool Contains(VMWareSnapshot item) { return Snapshots.Contains(item); } /// /// Number of snapshots. /// public int Count { get { return Snapshots.Count; } } /// /// Returns true if the collection is read-only. /// A collection of snapshots is never read-only. /// public bool IsReadOnly { get { return false; } } /// /// A snapshot collection enumerator. /// /// Snapshots enumerator. IEnumerator IEnumerable.GetEnumerator() { return Snapshots.GetEnumerator(); } /// /// A snapshot collection enumerator. /// /// Snapshots enumerator. IEnumerator IEnumerable.GetEnumerator() { return Snapshots.GetEnumerator(); } /// /// Add a snapshot to the list. /// /// Snapshot to add. public void Add(VMWareSnapshot snapshot) { if (snapshot.Parent != null && snapshot.Parent != _parent) { throw new InvalidOperationException("Snapshot already belongs to another collection."); } Snapshots.Add(snapshot); } /// /// Remove a snapshot from this collection, append orphaned children. /// /// Snapshot to remove. public void Remove(VMWareSnapshot snapshot) { if (_snapshots != null) { _snapshots.Remove(snapshot); foreach (VMWareSnapshot childSnapshot in snapshot.ChildSnapshots) { childSnapshot.Parent = _parent; _snapshots.Add(childSnapshot); } } } /// /// Remove all elements from the snapshot collection. /// public void RemoveAll() { if (_snapshots != null) { foreach (VMWareSnapshot snapshot in _snapshots) { snapshot.Dispose(); } _snapshots = null; } } /// /// Dispose the collection. /// public void Dispose() { RemoveAll(); _parent = null; _vm = null; } } }