private async Task <Tuple <Guid, string> > GetExpandedPackageData(string volumePath, CancellationToken cancellationToken) { Logger.Debug("Getting GUID and extracted path from volume {0}...", volumePath); var wrapper = new DiskPartWrapper(); var mountedVhd = false; try { var allDrives = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveFormat == "NTFS").Select(d => d.Name.ToLowerInvariant()).ToArray(); var existing = await MountVolumeHelper.GetVolumeIdentifiers().ConfigureAwait(false); Logger.Debug("Mounting {0}...", volumePath); await wrapper.MountVhd(volumePath, cancellationToken).ConfigureAwait(false); mountedVhd = true; var newVolumes = (await MountVolumeHelper.GetVolumeIdentifiers().ConfigureAwait(false)).Except(existing).ToArray(); var newDrives = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveFormat == "NTFS").Select(d => d.Name.ToLowerInvariant()).Except(allDrives).ToArray(); if (newDrives.Length != 1 || newVolumes.Length != 1) { throw new InvalidOperationException("Could not mount the drive."); } var dir = new DirectoryInfo(newDrives[0]); var msixFolderName = dir.EnumerateDirectories().FirstOrDefault()?.EnumerateDirectories().FirstOrDefault()?.Name; if (msixFolderName == null) { throw new InvalidOperationException("Could not read the content of the mounted file."); } return(new Tuple <Guid, string>(newVolumes[0], msixFolderName)); } finally { if (mountedVhd) { Logger.Debug("Dismounting {0}...", volumePath); await wrapper.DismountVhd(volumePath, cancellationToken).ConfigureAwait(false); } } }
public async Task CreateVolume( string packagePath, string volumePath, long?customSize, CancellationToken cancellationToken = default, IProgress <ProgressData> progressReporter = null) { if (packagePath == null) { throw new ArgumentNullException(nameof(packagePath), "Package path must not be empty."); } if (volumePath == null) { throw new ArgumentNullException(nameof(volumePath), "Volume path must not be empty."); } var packageFileInfo = new FileInfo(packagePath); if (!packageFileInfo.Exists) { throw new FileNotFoundException($"File {packagePath} does not exist.", packagePath); } switch (Path.GetExtension(volumePath).ToLowerInvariant()) { case FileConstants.AppAttachVhdExtension: case FileConstants.AppAttachVhdxExtension: break; default: throw new NotSupportedException($"Disk format {Path.GetExtension(volumePath)} is not supported."); } var volumeFileInfo = new FileInfo(volumePath); if (volumeFileInfo.Directory != null && !volumeFileInfo.Directory.Exists) { volumeFileInfo.Directory.Create(); } var tmpPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + Path.GetExtension(volumePath)); using var progress = new WrappedProgress(progressReporter); // ReSharper disable once UnusedVariable var progressSize = customSize <= 0 ? progress.GetChildProgress(30) : null; var progressInitializeDisk = progress.GetChildProgress(100); var progressExpand = progress.GetChildProgress(120); try { long minimumSize; if (customSize.HasValue && customSize.Value > 0) { minimumSize = 1024 * 1024 * customSize.Value; } else { ISizeCalculator sizeCalculator = new VhdSizeCalculator(); minimumSize = await sizeCalculator.GetRequiredSize(packagePath, cancellationToken : cancellationToken).ConfigureAwait(false); } var wrapper = new DiskPartWrapper(); try { Logger.Debug("Getting drives (NTFS, ready) and volumes..."); var allDrives = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveFormat == "NTFS").Select(d => d.Name.ToLowerInvariant()).ToArray(); foreach (var item in allDrives) { Logger.Debug("* Drive: " + item); } var allVolumes = await MountVolumeHelper.GetVolumeIdentifiers().ConfigureAwait(false); foreach (var item in allDrives) { Logger.Debug("* Volume: " + item); } await wrapper.CreateVhdAndAssignDriveLetter(tmpPath, minimumSize, cancellationToken, progressInitializeDisk).ConfigureAwait(false); var newVolumes = (await MountVolumeHelper.GetVolumeIdentifiers().ConfigureAwait(false)).Except(allVolumes).ToArray(); foreach (var item in newVolumes) { Logger.Debug("* New volume: " + item); } var newDrives = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveFormat == "NTFS").Select(d => d.Name.ToLowerInvariant()).Except(allDrives).ToArray(); foreach (var item in newDrives) { Logger.Debug("* New drive: " + item); } if (newDrives.Length != 1 || newVolumes.Length != 1) { throw new InvalidOperationException("Could not mount the drive."); } cancellationToken.ThrowIfCancellationRequested(); await this.ExpandMsix(packagePath, newDrives.First() + Path.GetFileNameWithoutExtension(packagePath), cancellationToken, progressExpand).ConfigureAwait(false); } finally { await wrapper.DismountVhd(tmpPath, cancellationToken).ConfigureAwait(false); } if (File.Exists(tmpPath)) { File.Move(tmpPath, volumeFileInfo.FullName, true); } } finally { if (File.Exists(tmpPath)) { File.Delete(tmpPath); } } }