protected sealed override async Task <int> ExecuteOnExtractedPackage(string directoryPath) { var manifestFile = Path.Combine(directoryPath, FileConstants.AppxManifestFile); if (!File.Exists(manifestFile)) { throw new FileNotFoundException($"Manifest file {manifestFile} does not exist."); } XDocument document; int result; { await using var fs = File.OpenRead(manifestFile); document = await XDocument.LoadAsync(fs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false); var rootNode = document.Root; if (rootNode?.Name.LocalName != "Package") { throw new FormatException("XML file must contain root <Package /> element."); } result = await this.ExecuteOnManifest(document).ConfigureAwait(false); var brandingInjector = new MsixHeroBrandingInjector(); await brandingInjector.Inject(document).ConfigureAwait(false); } var writer = new AppxDocumentWriter(document); await writer.WriteAsync(manifestFile).ConfigureAwait(false); return(result); }
public async Task Pack( string directory, string packagePath, IDictionary <string, string> extraFiles, AppxPackerOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { if (!Directory.Exists(directory)) { throw new DirectoryNotFoundException($"Folder {directory} does not exist."); } var fileInfo = new FileInfo(packagePath); if (fileInfo.Directory == null) { throw new ArgumentException($"File path {packagePath} is not supported.", nameof(packagePath)); } if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } var tempFile = Path.GetTempFileName(); var tempManifestFilePath = Path.GetTempFileName(); var tempAutoGenerated = Path.GetTempFileName(); try { var inputDirectory = new DirectoryInfo(directory); var listBuilder = new PackageFileListBuilder(); foreach (var item in inputDirectory.EnumerateFiles("*", SearchOption.AllDirectories)) { cancellationToken.ThrowIfCancellationRequested(); var relativePath = Path.GetRelativePath(directory, item.FullName); if (string.IsNullOrEmpty(relativePath)) { continue; } // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (string.Equals(FileConstants.AppxManifestFile, relativePath, StringComparison.OrdinalIgnoreCase)) { listBuilder.AddManifest(tempManifestFilePath); item.CopyTo(tempManifestFilePath, true); continue; } listBuilder.AddFile(item.FullName, relativePath); } if (extraFiles != null) { foreach (var item in extraFiles) { cancellationToken.ThrowIfCancellationRequested(); if (string.Equals(Path.GetFileName(item.Key), FileConstants.AppxManifestFile, StringComparison.OrdinalIgnoreCase)) { tempManifestFilePath = item.Value; listBuilder.AddFile(item.Value, item.Key); } else { listBuilder.AddFile(item.Value, item.Key); } } } var allDirs = inputDirectory.EnumerateDirectories("*", SearchOption.AllDirectories); foreach (var emptyDir in allDirs.Where(d => !d.EnumerateFiles("*", SearchOption.TopDirectoryOnly).Any() && !d.EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Any())) { // this means we have an empty folder, which requires some special handling if (new FileInfo(tempAutoGenerated).Length == 0) { await File.WriteAllBytesAsync(tempAutoGenerated, Array.Empty <byte>(), cancellationToken).ConfigureAwait(false); } var relativePath = Path.GetRelativePath(inputDirectory.FullName, emptyDir.FullName); listBuilder.AddFile(tempAutoGenerated, $"{relativePath}\\GeneratedFile.txt\""); } await File.WriteAllTextAsync(tempFile, listBuilder.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); XDocument xmlManifestDocument; await using (var tempManifestStream = File.OpenRead(tempManifestFilePath)) { using var tempManifestReader = new StreamReader(tempManifestStream); xmlManifestDocument = await XDocument.LoadAsync(tempManifestReader, LoadOptions.None, cancellationToken).ConfigureAwait(false); var injector = new MsixHeroBrandingInjector(); await injector.Inject(xmlManifestDocument).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); var appxWriter = new AppxDocumentWriter(xmlManifestDocument); await appxWriter.WriteAsync(tempManifestFilePath).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var compress = !options.HasFlag(AppxPackerOptions.NoCompress); var validate = !options.HasFlag(AppxPackerOptions.NoValidation); await new MakeAppxWrapper().PackPackageFiles(tempFile, packagePath, compress, validate, cancellationToken, progress).ConfigureAwait(false); } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } if (File.Exists(tempManifestFilePath)) { File.Delete(tempManifestFilePath); } if (File.Exists(tempAutoGenerated)) { File.Delete(tempAutoGenerated); } } }
public async Task Finish(CancellationToken cancellationToken = default) { var path = Path.Combine(this.directoryInfo.FullName, "AppxManifest.xml"); var writer = new AppxDocumentWriter(this.manifest); await writer.WriteAsync(path).ConfigureAwait(false); }
public override async Task <int> Execute() { try { await this.OnBegin().ConfigureAwait(false); if (!File.Exists(this.package) && !Directory.Exists(this.package)) { await this.Console.WriteError($"The path {this.package} does not exist."); return(10); } var validation = await this.Validate().ConfigureAwait(false); if (validation != 0) { return(validation); } if (File.Exists(this.package)) { // This is a file... if (string.Equals(Path.GetFileName(this.package), FileConstants.AppxManifestFile, StringComparison.OrdinalIgnoreCase)) { // .. a manifest file var result = await this.ExecuteOnExtractedPackage(Path.GetDirectoryName(this.package)).ConfigureAwait(false); await this.OnFinished().ConfigureAwait(false); return(result); } if (string.Equals(".msix", Path.GetExtension(this.package))) { // .. an MSIX package var msixMgr = new MakeAppxWrapper(); var tempFolder = Path.Combine(Path.GetTempPath(), "msixhero-" + Guid.NewGuid().ToString("N").Substring(0, 8)); try { await this.Console.WriteInfo($"Opening {Path.GetFileName(this.package)}...").ConfigureAwait(false); // 1) Unpack first await msixMgr.UnpackPackage(this.package, tempFolder, false).ConfigureAwait(false); // 2) Make edit var result = await this.ExecuteOnExtractedPackage(tempFolder).ConfigureAwait(false); if (result != StandardExitCodes.ErrorSuccess) { await this.Console.WriteWarning($"The package has not been updated due to previous errors.").ConfigureAwait(false); return(result); } // 3) Add branding XDocument document; await using (var fs = File.OpenRead(Path.Combine(tempFolder, "AppxManifest.xml"))) { document = await XDocument.LoadAsync(fs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false); } var inject = new MsixHeroBrandingInjector(); await inject.Inject(document).ConfigureAwait(false); var writer = new AppxDocumentWriter(document); await writer.WriteAsync(Path.Combine(tempFolder, "AppxManifest.xml")).ConfigureAwait(false); if (result == StandardExitCodes.ErrorSuccess) { await this.Console.WriteInfo($"Saving {Path.GetFileName(this.package)}...").ConfigureAwait(false); // 3) Pack again await msixMgr.PackPackageDirectory(tempFolder, this.package, false, false); await this.OnFinished().ConfigureAwait(false); } return(result); } finally { if (Directory.Exists(tempFolder)) { ExceptionGuard.Guard(() => Directory.Delete(tempFolder, true)); } } } } else if (Directory.Exists(this.package)) { // this is extracted directory var manifestPath = Path.Combine(this.package, FileConstants.AppxManifestFile); if (File.Exists(manifestPath)) { var result = await this.ExecuteOnExtractedPackage(this.package).ConfigureAwait(false); XDocument document; await using (var fs = File.OpenRead(manifestPath)) { document = await XDocument.LoadAsync(fs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false); } var inject = new MsixHeroBrandingInjector(); await inject.Inject(document).ConfigureAwait(false); var writer = new AppxDocumentWriter(document); await writer.WriteAsync(manifestPath).ConfigureAwait(false); await this.OnFinished().ConfigureAwait(false); return(result); } } await this.Console.WriteError($"The path {this.package} is neither a directory with extracted MSIX, an .MSIX package or a manifest file.").ConfigureAwait(false); return(StandardExitCodes.ErrorParameter); } catch (Exception e) { await this.Console.WriteError(e.Message).ConfigureAwait(false); return(StandardExitCodes.ErrorGeneric); } }