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 TestSimpleInjection() { var manifest = this.PrepareMockManifest(); var injector = new MsixHeroBrandingInjector(); await injector.Inject(manifest).ConfigureAwait(false); Assert.NotNull(GetBuildVersion(manifest, "MsixHero")); Assert.NotNull(GetBuildVersion(manifest, "OperatingSystem")); Assert.NotNull(GetBuildVersion(manifest, "SignTool.exe")); Assert.NotNull(GetBuildVersion(manifest, "MakePri.exe")); Assert.NotNull(GetBuildVersion(manifest, "MakeAppx.exe")); }
public async Task PackFiles( string directory, string packagePath, AppxPackerOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default) { var manifestFile = Path.Combine(directory, FileConstants.AppxManifestFile); if (!File.Exists(manifestFile)) { throw new FileNotFoundException("Manifest file has not been found.", manifestFile); } XDocument xmlDocument; await using (var stream = File.OpenRead(manifestFile)) { using var streamReader = new StreamReader(stream); xmlDocument = await XDocument.LoadAsync(streamReader, LoadOptions.None, cancellationToken).ConfigureAwait(false); } var injector = new MsixHeroBrandingInjector(); await injector.Inject(xmlDocument).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await File.WriteAllTextAsync(manifestFile, xmlDocument.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var compress = !options.HasFlag(AppxPackerOptions.NoCompress); var validate = !options.HasFlag(AppxPackerOptions.NoValidation); var allDirs = new DirectoryInfo(directory).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 await File.WriteAllBytesAsync(Path.Combine(emptyDir.FullName, "GeneratedFile.txt"), Array.Empty <byte>(), cancellationToken).ConfigureAwait(false); } await new MakeAppxWrapper().PackPackageDirectory(directory, packagePath, compress, validate, cancellationToken, progress).ConfigureAwait(false); }
public async Task TestOverridingDefault() { var existingValues = new Dictionary <string, string> { { "MsixHero", "91.0" }, { "OperatingSystem", "92.0" }, { "MakePri.exe", "93.0" }, { "SignTool.exe", "94.0" }, { "MakeAppx.exe", "95.0" }, }; var manifest = this.PrepareMockManifest(existingValues); var injector = new MsixHeroBrandingInjector(); await injector.Inject(manifest); Assert.AreNotEqual("91.0", GetBuildVersion(manifest, "MsixHero"), "By default this value must be overridden."); Assert.AreEqual("92.0", GetBuildVersion(manifest, "OperatingSystem"), "By default this value must not be overridden."); Assert.AreEqual("93.0", GetBuildVersion(manifest, "MakePri.exe"), "By default this value must not be overridden."); Assert.AreNotEqual("94.0", GetBuildVersion(manifest, "SignTool.exe"), "By default this value must be overridden."); Assert.AreNotEqual("95.0", GetBuildVersion(manifest, "MakeAppx.exe"), "By default this value must be overridden."); }
public async Task TestOverridingPreferExisting() { var existingValues = new Dictionary <string, string> { { "MsixHero", "91.0" }, { "OperatingSystem", "92.0" }, { "MakePri.exe", "93.0" }, { "SignTool.exe", "94.0" }, { "MakeAppx.exe", "95.0" }, }; var manifest = this.PrepareMockManifest(existingValues); var injector = new MsixHeroBrandingInjector(); await injector.Inject(manifest, MsixHeroBrandingInjector.BrandingInjectorOverrideOption.PreferExisting); Assert.AreNotEqual("91.0", GetBuildVersion(manifest, "MsixHero"), "This value must be always overridden."); Assert.AreEqual("92.0", GetBuildVersion(manifest, "OperatingSystem"), "This value must not be overridden."); Assert.AreEqual("93.0", GetBuildVersion(manifest, "MakePri.exe"), "This value must not be overridden."); Assert.AreEqual("94.0", GetBuildVersion(manifest, "SignTool.exe"), "This value must not be overridden."); Assert.AreEqual("95.0", GetBuildVersion(manifest, "MakeAppx.exe"), "This value must not be overridden."); var existingIncompleteValues = new Dictionary <string, string> { { "SignTool.exe", "94.0" }, { "MakeAppx.exe", "95.0" }, }; manifest = this.PrepareMockManifest(existingIncompleteValues); await injector.Inject(manifest, MsixHeroBrandingInjector.BrandingInjectorOverrideOption.PreferExisting); Assert.NotNull(GetBuildVersion(manifest, "MsixHero")); Assert.NotNull(GetBuildVersion(manifest, "OperatingSystem")); Assert.NotNull(GetBuildVersion(manifest, "MakePri.exe")); Assert.AreEqual("94.0", GetBuildVersion(manifest, "SignTool.exe"), "This value must not be overridden."); Assert.AreEqual("95.0", GetBuildVersion(manifest, "MakeAppx.exe"), "This value must not be overridden."); }
public async Task Pack(string directory, string packagePath, 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 tempManifest = Path.GetTempFileName(); var tempAutoGenerated = Path.GetTempFileName(); try { var inputDirectory = new DirectoryInfo(directory); var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[Files]"); 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)) { stringBuilder.AppendLine($"\"{tempManifest}\"\t\"{relativePath}\""); item.CopyTo(tempManifest, true); continue; } if ( string.Equals("AppxBlockMap.xml", relativePath, StringComparison.OrdinalIgnoreCase) || string.Equals("AppxSignature.p7x", relativePath, StringComparison.OrdinalIgnoreCase)) { continue; } stringBuilder.AppendLine($"\"{item.FullName}\"\t\"{relativePath}\""); } 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, new byte[0], cancellationToken).ConfigureAwait(false); } var relativePath = Path.GetRelativePath(inputDirectory.FullName, emptyDir.FullName); stringBuilder.AppendLine($"\"{tempAutoGenerated}\"\t\"{relativePath}\\GeneratedFile.txt\""); } await File.WriteAllTextAsync(tempFile, stringBuilder.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); var xmlDocument = XDocument.Load(tempManifest); var injector = new MsixHeroBrandingInjector(); injector.Inject(xmlDocument); cancellationToken.ThrowIfCancellationRequested(); await File.WriteAllTextAsync(tempManifest, xmlDocument.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var compress = !options.HasFlag(AppxPackerOptions.NoCompress); var validate = !options.HasFlag(AppxPackerOptions.NoValidation); await new MsixSdkWrapper().PackPackageFiles(tempFile, packagePath, compress, validate, cancellationToken, progress).ConfigureAwait(false); } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } if (File.Exists(tempManifest)) { File.Delete(tempManifest); } if (File.Exists(tempAutoGenerated)) { File.Delete(tempAutoGenerated); } } }
private async Task PrepareModificationPackage(XDocument template, ModificationPackageConfig config) { XNamespace nsUap4 = "http://schemas.microsoft.com/appx/manifest/uap/windows10/4"; XNamespace nsUap6 = "http://schemas.microsoft.com/appx/manifest/uap/windows10/6"; XNamespace nsRescap = "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"; XNamespace nsRescap6 = "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/6"; XNamespace nsBuild = "http://schemas.microsoft.com/developer/appx/2015/build"; XNamespace defaultNamespace = "http://schemas.microsoft.com/appx/manifest/foundation/windows10"; var root = template.Root; if (root == null) { root = new XElement(defaultNamespace + "Package"); template.Add(root); } else { defaultNamespace = root.GetDefaultNamespace(); } if (root.GetPrefixOfNamespace(nsUap4) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "uap4", nsUap6.NamespaceName)); } if (root.GetPrefixOfNamespace(nsUap6) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "uap6", nsUap6.NamespaceName)); } if (root.GetPrefixOfNamespace(nsRescap) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "rescap", nsRescap.NamespaceName)); } if (root.GetPrefixOfNamespace(nsRescap6) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "rescap6", nsRescap6.NamespaceName)); } if (root.GetPrefixOfNamespace(nsBuild) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "build", nsBuild.NamespaceName)); } var package = GetOrCreateNode(template, "Package", defaultNamespace); var dependencies = GetOrCreateNode(package, "Dependencies", defaultNamespace); var dependency = new XElement(nsUap4 + "MainPackageDependency"); dependencies.Add(dependency); var parentName = config.ParentName; var parentPublisher = config.ParentPublisher; if (string.IsNullOrEmpty(parentPublisher) || string.IsNullOrEmpty(parentName)) { IAppxFileReader reader = null; try { if (string.Equals(FileConstants.AppxManifestFile, Path.GetFileName(config.ParentPackagePath), StringComparison.OrdinalIgnoreCase)) { reader = new FileInfoFileReaderAdapter(config.ParentPackagePath); } else { reader = new ZipArchiveFileReaderAdapter(config.ParentPackagePath); } var manifestReader = new AppxManifestReader(); var read = await manifestReader.Read(reader).ConfigureAwait(false); if (string.IsNullOrEmpty(parentPublisher)) { parentPublisher = read.Publisher; } if (string.IsNullOrEmpty(parentName)) { parentName = read.Name; } } finally { reader?.Dispose(); } } dependency.SetAttributeValue("Name", parentName); dependency.SetAttributeValue("Publisher", parentPublisher); var identity = GetOrCreateNode(package, "Identity", defaultNamespace); identity.SetAttributeValue("Name", config.Name); identity.SetAttributeValue("Publisher", config.Publisher); var fixVersion = Version.Parse(config.Version); var major = fixVersion.Major; var minor = fixVersion.Minor; var build = fixVersion.Build; var revision = fixVersion.Revision; if (major < 0) { throw new FormatException("Invalid version format, major version is required."); } if (minor < 0) { throw new FormatException("Invalid version format, major version is required."); } if (revision < 0) { revision = 0; } if (build < 0) { build = 0; } identity.SetAttributeValue("Version", new Version(major, minor, build, revision).ToString(4)); var properties = GetOrCreateNode(package, "Properties", defaultNamespace); GetOrCreateNode(properties, "DisplayName", defaultNamespace).Value = config.DisplayName ?? "Modification Package Name"; GetOrCreateNode(properties, "PublisherDisplayName", defaultNamespace).Value = config.DisplayPublisher ?? "Modification Package Publisher Name"; GetOrCreateNode(properties, "Description", defaultNamespace).Value = "Modification Package for " + parentName; GetOrCreateNode(properties, "Logo", defaultNamespace).Value = "Assets\\Logo.png"; GetOrCreateNode(properties, "ModificationPackage", nsRescap6).Value = "true"; var branding = new MsixHeroBrandingInjector(); branding.Inject(template); }
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); } } }
private async Task AdjustManifest(XDocument template, AppxManifestCreatorOptions config, DirectoryInfo baseDirectory, string[] entryPoints) { XNamespace nsUap = "http://schemas.microsoft.com/appx/manifest/uap/windows10"; XNamespace nsUap4 = "http://schemas.microsoft.com/appx/manifest/uap/windows10/4"; XNamespace nsUap6 = "http://schemas.microsoft.com/appx/manifest/uap/windows10/6"; XNamespace defaultNamespace = "http://schemas.microsoft.com/appx/manifest/foundation/windows10"; var root = template.Root; if (root == null) { root = new XElement(defaultNamespace + "Package"); template.Add(root); } else { defaultNamespace = root.GetDefaultNamespace(); } // Add capability var addCapability = new AddCapability("runFullTrust"); var capabilityExecutor = new AddCapabilityExecutor(template); await capabilityExecutor.Execute(addCapability).ConfigureAwait(false); // Set identity var setIdentity = new SetPackageIdentity { Name = config.PackageName, Publisher = config.PublisherName, ProcessorArchitecture = config.PackageArchitecture.ToString("G").ToLowerInvariant() }; var major = config.Version.Major; var minor = config.Version.Minor; var build = config.Version.Build; var revision = config.Version.Revision; if (major < 0) { throw new FormatException("Invalid version format, major version is required."); } if (minor < 0) { throw new FormatException("Invalid version format, major version is required."); } if (revision < 0) { revision = 0; } if (build < 0) { build = 0; } setIdentity.Version = new Version(major, minor, build, revision).ToString(); var executor = new SetPackageIdentityExecutor(template); await executor.Execute(setIdentity).ConfigureAwait(false); // Add namespaces (legacy) if (root.GetPrefixOfNamespace(nsUap) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "uap", nsUap.NamespaceName)); } if (root.GetPrefixOfNamespace(nsUap4) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "uap4", nsUap6.NamespaceName)); } if (root.GetPrefixOfNamespace(nsUap6) == null) { root.Add(new XAttribute(XNamespace.Xmlns + "uap6", nsUap6.NamespaceName)); } var package = GetOrCreateNode(template, "Package", defaultNamespace); var properties = GetOrCreateNode(package, "Properties", defaultNamespace); GetOrCreateNode(properties, "DisplayName", defaultNamespace).Value = config.PackageDisplayName ?? config.PackageName ?? "DisplayName"; GetOrCreateNode(properties, "Description", defaultNamespace).Value = config.PackageDisplayName ?? config.PackageName ?? "Description"; GetOrCreateNode(properties, "PublisherDisplayName", defaultNamespace).Value = config.PublisherDisplayName ?? config.PublisherName ?? "Publisher"; GetOrCreateNode(properties, "Logo", defaultNamespace).Value = "Assets\\Logo.png"; var applicationsNode = GetOrCreateNode(package, "Applications", defaultNamespace); var usedNames = new HashSet<string>(); foreach (var item in entryPoints) { var applicationNode = this.CreateApplicationNodeFromExe(baseDirectory, item); applicationsNode.Add(applicationNode); var idCandidate = Regex.Replace(Path.GetFileNameWithoutExtension(item), "[^a-zA-z0-9_]+", string.Empty); if (!usedNames.Add(idCandidate)) { var index = 1; var baseIdCandidate = idCandidate; while (!usedNames.Add(baseIdCandidate + "_" + index)) { index++; } idCandidate = baseIdCandidate + "_" + index; } applicationNode.SetAttributeValue("Id", idCandidate); } var branding = new MsixHeroBrandingInjector(); await branding.Inject(template, MsixHeroBrandingInjector.BrandingInjectorOverrideOption.PreferIncoming).ConfigureAwait(false); }
protected override async Task <bool> Save(CancellationToken cancellationToken, IProgress <ProgressData> progress) { var temporaryFiles = new List <string>(); try { var fileListBuilder = new PackageFileListBuilder(); fileListBuilder.AddDirectory(this.InputPath.CurrentValue, true, null); if (this.PrePackOptions != null && !this.PrePackOptions.ManifestPresent) { if (!this.PrePackOptions.CanConvert) { throw new InvalidOperationException("The selected folder does not contain a manifest file and any executable files. It cannot be packed to MSIX format."); } if (!string.IsNullOrEmpty(this.InputPath.CurrentValue)) { progress.Report(new ProgressData(0, "Creating manifest file...")); var options = new AppxManifestCreatorOptions { CreateLogo = this.PrePackOptions.CreateLogo, EntryPoints = this.PrePackOptions.EntryPoints.Where(e => e.IsChecked).Select(e => e.Value).ToArray(), PackageDisplayName = Path.GetFileName(this.InputPath.CurrentValue), RegistryFile = this.PrePackOptions.SelectedRegistry?.FilePath == null ? null : new FileInfo(this.PrePackOptions.SelectedRegistry.FilePath) }; // ReSharper disable once AssignNullToNotNullAttribute await foreach (var result in this.manifestCreator.CreateManifestForDirectory(new DirectoryInfo(this.InputPath.CurrentValue), options, cancellationToken).ConfigureAwait(false)) { temporaryFiles.Add(result.SourcePath); if (result.PackageRelativePath == null) { continue; } fileListBuilder.AddFile(result.SourcePath, result.PackageRelativePath); } } } using var progressWrapper = new WrappedProgress(progress); var progress1 = progressWrapper.GetChildProgress(50); var progress2 = this.Sign.CurrentValue ? progressWrapper.GetChildProgress(30) : null; var tempFileList = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".list"); temporaryFiles.Add(tempFileList); var tempManifestPath = Path.Combine(Path.GetTempPath(), "AppxManifest-" + Guid.NewGuid().ToString("N") + ".xml"); temporaryFiles.Add(tempManifestPath); var srcManifest = fileListBuilder.GetManifestSourcePath(); if (srcManifest == null || !File.Exists(srcManifest)) { throw new InvalidOperationException("The selected folder cannot be packed because it has no manifest, and MSIX Hero was unable to create one. A manifest can be only created if the selected folder contains any executable file."); } // Copy manifest to a temporary file var injector = new MsixHeroBrandingInjector(); await using (var manifestStream = File.OpenRead(fileListBuilder.GetManifestSourcePath())) { var xml = await XDocument.LoadAsync(manifestStream, LoadOptions.None, cancellationToken).ConfigureAwait(false); await injector.Inject(xml).ConfigureAwait(false); await File.WriteAllTextAsync(tempManifestPath, xml.ToString(SaveOptions.None), cancellationToken); fileListBuilder.AddManifest(tempManifestPath); } await File.WriteAllTextAsync(tempFileList, fileListBuilder.ToString(), cancellationToken).ConfigureAwait(false); var sdk = new MakeAppxWrapper(); await sdk.PackPackageFiles(tempFileList, this.OutputPath.CurrentValue, this.Compress.CurrentValue, this.Validate.CurrentValue, cancellationToken, progress1).ConfigureAwait(false); if (this.Sign.CurrentValue) { var manager = await this.signingManagerFactory.GetProxyFor(SelfElevationLevel.HighestAvailable, cancellationToken).ConfigureAwait(false); string timeStampUrl; switch (this.SelectedCertificate.TimeStampSelectionMode.CurrentValue) { case TimeStampSelectionMode.None: timeStampUrl = null; break; case TimeStampSelectionMode.Auto: timeStampUrl = "auto"; break; case TimeStampSelectionMode.Url: timeStampUrl = this.SelectedCertificate.TimeStamp.CurrentValue; break; default: throw new ArgumentOutOfRangeException(); } switch (this.SelectedCertificate.Store.CurrentValue) { case CertificateSource.Personal: await manager.SignPackageWithInstalled(this.OutputPath.CurrentValue, this.OverrideSubject.CurrentValue, this.SelectedCertificate.SelectedPersonalCertificate.CurrentValue?.Model, timeStampUrl, IncreaseVersionMethod.None, cancellationToken, progress2).ConfigureAwait(false); break; case CertificateSource.Pfx: await manager.SignPackageWithPfx(this.OutputPath.CurrentValue, this.OverrideSubject.CurrentValue, this.SelectedCertificate.PfxPath.CurrentValue, this.SelectedCertificate.Password.CurrentValue, timeStampUrl, IncreaseVersionMethod.None, cancellationToken, progress2).ConfigureAwait(false); break; case CertificateSource.DeviceGuard: await manager.SignPackageWithDeviceGuardFromUi(this.OutputPath.CurrentValue, this.SelectedCertificate.DeviceGuard.CurrentValue, timeStampUrl, IncreaseVersionMethod.None, cancellationToken, progress2).ConfigureAwait(false); break; } } if (this.RemoveDirectory.CurrentValue) { ExceptionGuard.Guard(() => Directory.Delete(this.InputPath.CurrentValue, true)); } return(true); } finally { foreach (var tempFile in temporaryFiles) { ExceptionGuard.Guard(() => File.Delete(tempFile)); } } }
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); } }