public DirectoryInfoFileReaderAdapter(DirectoryInfo appxManifestFolder) { if (!appxManifestFolder.Exists) { throw new ArgumentException($"Directory {appxManifestFolder.FullName} does not exist."); } this.RootDirectory = appxManifestFolder.FullName; var appxManifest = Path.Combine(appxManifestFolder.FullName, FileConstants.AppxManifestFile); if (!File.Exists(appxManifest)) { appxManifest = Path.Combine(appxManifestFolder.FullName, FileConstants.AppxBundleManifestFilePath); if (!File.Exists(appxManifest)) { throw new ArgumentException("This folder does not contain APPX/MSIX package nor APPX bundle.", nameof(appxManifestFolder)); } adapter = new FileInfoFileReaderAdapter(appxManifest); } else { adapter = new FileInfoFileReaderAdapter(Path.Combine(appxManifestFolder.FullName, FileConstants.AppxManifestFile)); } }
public async Task <AppxBundle> ReadBundle(IAppxFileReader fileReader, CancellationToken cancellationToken) { var bundle = new AppxBundle(); using (var file = fileReader.GetFile(FileConstants.AppxBundleManifestFilePath)) { var document = await XDocument.LoadAsync(file, LoadOptions.None, cancellationToken).ConfigureAwait(false); if (document.Root == null) { throw new FormatException("The manifest is malformed. There is no root element."); } // var b4 = XNamespace.Get("http://schemas.microsoft.com/appx/2018/bundle"); // var b5 = XNamespace.Get("http://schemas.microsoft.com/appx/2019/bundle"); var ns = XNamespace.Get("http://schemas.microsoft.com/appx/2013/bundle"); var identity = document.Root.Element(ns + "Identity"); if (identity == null) { throw new FormatException("The manifest is malformed, missing <Identity />."); } bundle.Version = identity.Attribute("Version")?.Value; bundle.Name = identity.Attribute("Name")?.Value; bundle.Publisher = identity.Attribute("Publisher")?.Value; } return(bundle); }
// ReSharper disable once MemberCanBeMadeStatic.Local private async Task <AppxPackage> LoadManifest(IAppxFileReader fileReader, CancellationToken cancellation = default) { var manifestReader = new AppxManifestReader(); var manifest = await manifestReader.Read(fileReader, cancellation).ConfigureAwait(false); return(manifest); }
// ReSharper disable once MemberCanBeMadeStatic.Local private async Task <PsfContentViewModel> LoadPsf(IAppxFileReader source, AppxPackage manifest) { var paths = manifest.Applications.Where(a => PackageTypeConverter.GetPackageTypeFrom(a.EntryPoint, a.Executable, a.StartPage, manifest.IsFramework) == MsixPackageType.BridgePsf).Select(a => a.Executable).Where(a => a != null).Select(Path.GetDirectoryName).Where(a => !string.IsNullOrEmpty(a)).Distinct().ToList(); paths.Add(string.Empty); foreach (var items in paths) { var configJsonPath = string.IsNullOrWhiteSpace(items) ? "config.json" : Path.Combine(items, "config.json"); if (!source.FileExists(configJsonPath)) { continue; } using (var s = source.GetFile(configJsonPath)) { using var stringReader = new StreamReader(s); var all = await stringReader.ReadToEndAsync().ConfigureAwait(false); var psfSerializer = new PsfConfigSerializer(); var configJson = psfSerializer.Deserialize(all); return(new PsfContentViewModel(configJson)); } } return(null); }
public Stream GetResource(string resourceFilePath) { if (string.IsNullOrEmpty(resourceFilePath)) { return(null); } if (this.adapter == null) { this.adapter = this.GetAdapter(); } return(this.adapter.GetResource(resourceFilePath)); }
public Stream GetFile(string filePath) { if (string.IsNullOrEmpty(filePath)) { return(null); } if (this.adapter == null) { this.adapter = this.GetAdapter(); } return(this.adapter.GetFile(filePath)); }
public bool FileExists(string filePath) { if (string.IsNullOrEmpty(filePath)) { return(false); } if (this.adapter == null) { this.adapter = this.GetAdapter(); } return(this.adapter.FileExists(filePath)); }
public Task <AppxPackage> Read(IAppxFileReader fileReader, CancellationToken cancellationToken = default) { var isMsix = fileReader.FileExists(FileConstants.AppxManifestFile); if (isMsix) { return(this.ReadMsix(fileReader, FileConstants.AppxManifestFile, cancellationToken)); } var isAppxBundle = fileReader.FileExists(FileConstants.AppxBundleManifestFilePath); if (isAppxBundle) { throw new NotSupportedException("Bundles are not supported."); } throw new NotSupportedException("Required package source is not supported."); }
public async Task <string> GetDiskPath(IAppxFileReader fileReader, string filePath) { if (!fileReader.FileExists(filePath)) { throw new FileNotFoundException(); } await using var fileStream = fileReader.GetFile(filePath); if (fileStream is FileStream fs) { // we can assume the file is directly accessible return(fs.Name); } var index = 0; string fullPath; this.tempDirectory ??= new DirectoryInfo(Path.Combine(Path.GetTempPath(), "MSIX-Hero", Guid.NewGuid().ToString("N").Substring(10))); while (true) { fullPath = Path.Combine(this.tempDirectory.FullName, index.ToString("0"), Path.GetFileName(filePath)); if (!File.Exists(fullPath)) { break; } index++; } var fileInfo = new FileInfo(fullPath); if (fileInfo.Directory?.Exists == false) { fileInfo.Directory.Create(); } await using var targetStream = File.OpenWrite(fileInfo.FullName); await fileStream.CopyToAsync(targetStream).ConfigureAwait(false); return(fileInfo.FullName); }
private void SourcePathOnValueChanged(object sender, ValueChangedEventArgs e) { try { using IAppxFileReader reader = FileReaderFactory.CreateFileReader((string)e.NewValue); var mr = new AppxManifestReader(); var read = mr.Read(reader).GetAwaiter().GetResult(); if (string.IsNullOrWhiteSpace(this.DisplayName.CurrentValue)) { this.DisplayName.CurrentValue = read.DisplayName + " - Modification package"; } this.ParentName.CurrentValue = read.Name; this.ParentPublisher.CurrentValue = read.Publisher; this.OnPropertyChanged(nameof(IsIncludeVfsFoldersEnabled)); } catch (Exception exception) { Logger.Error(exception); this.interactionService.ShowError("Could not read the properties from the package.", exception); } }
public async Task <AppxPackage> Read(IAppxFileReader fileReader, bool resolveDependencies, CancellationToken cancellationToken = default) { var result = await this.Read(fileReader, cancellationToken).ConfigureAwait(false); if (resolveDependencies) { foreach (var item in result.PackageDependencies) { cancellationToken.ThrowIfCancellationRequested(); using IAppxFileReader tempReader = new PackageIdentityFileReaderAdapter(PackageContext.CurrentUser, item.Name, item.Publisher, item.Version); try { item.Dependency = await this.Read(tempReader, cancellationToken).ConfigureAwait(false); } catch (Exception) { Logger.Warn("Could not read a dependency to {0} {2} by {1}", item.Name, item.Publisher, item.Version); } } } return(result); }
public AuthoringAppDetector(IAppxFileReader fileReader) { this.fileReader = fileReader; }
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); }
private async Task <YamlManifest> CreateFromMsix(string filePath, CancellationToken cancellationToken = default) { var yamlDefinition = new YamlManifest() { Installers = new List <YamlInstaller> { new YamlInstaller { Scope = YamlScope.User, InstallerType = YamlInstallerType.Msix } } }; using IAppxFileReader reader = FileReaderFactory.CreateFileReader(filePath); try { yamlDefinition.Installers[0].SignatureSha256 = await this.CalculateSignatureHashAsync(new FileInfo(filePath), cancellationToken).ConfigureAwait(false); } catch (ArgumentException) { } var manifestReader = new AppxManifestReader(); var details = await manifestReader.Read(reader, cancellationToken).ConfigureAwait(false); yamlDefinition.PackageName = details.DisplayName; yamlDefinition.Publisher = details.PublisherDisplayName; yamlDefinition.PackageVersion = details.Version; yamlDefinition.ShortDescription = details.Description; yamlDefinition.Installers[0].Capabilities = details.Capabilities?.Where(c => c.Type == CapabilityType.General || c.Type == CapabilityType.Device).Select(c => c.Name).ToList(); yamlDefinition.Installers[0].RestrictedCapabilities = details.Capabilities?.Where(c => c.Type == CapabilityType.Restricted).Select(c => c.Name).ToList(); if (details.Applications?.Any() == true) { // Exclude some unrelated PSF stuff - they are not the right choice for the app moniker. var candidateForAppMoniker = details.Applications.Select(a => a.Executable) .FirstOrDefault(a => !string.IsNullOrEmpty(a) && !a.StartsWith("psf", StringComparison.OrdinalIgnoreCase) && !a.StartsWith("AI_stubs", StringComparison.OrdinalIgnoreCase) && a.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)); yamlDefinition.Platform = new List <YamlPlatform>() { details.Applications.Any(a => a.EntryPoint == "Windows.FullTrustApplication") ? YamlPlatform.WindowsDesktop : YamlPlatform.WindowsUniversal }; if (!string.IsNullOrEmpty(candidateForAppMoniker)) { yamlDefinition.Moniker = candidateForAppMoniker.Substring(0, candidateForAppMoniker.Length - ".exe".Length).Split('\\', '/').Last(); } } switch (details.ProcessorArchitecture) { case AppxPackageArchitecture.Arm: yamlDefinition.Installers[0].Architecture = YamlArchitecture.Arm; break; case AppxPackageArchitecture.Neutral: yamlDefinition.Installers[0].Architecture = YamlArchitecture.Neutral; break; case AppxPackageArchitecture.Arm64: yamlDefinition.Installers[0].Architecture = YamlArchitecture.Arm64; break; case AppxPackageArchitecture.x86: yamlDefinition.Installers[0].Architecture = YamlArchitecture.X86; break; case AppxPackageArchitecture.x64: yamlDefinition.Installers[0].Architecture = YamlArchitecture.X64; break; } return(yamlDefinition); }
public PsfApplicationDescriptor Read(string applicationId, string originalEntryPoint, IAppxFileReader fileReader) { if ( string.Equals(originalEntryPoint, @"AI_STUBS\AiStub.exe", StringComparison.OrdinalIgnoreCase) || string.Equals(originalEntryPoint, @"AI_STUBS\AiStubElevated.exe", StringComparison.OrdinalIgnoreCase)) { if (fileReader.FileExists(@"AI_STUBS\AiStub.exe") || fileReader.FileExists(@"AI_STUBS\AiStubElevated.exe")) { // This is an old Advanced Installer stuff if (fileReader.FileExists("Registry.dat")) { RegistryHiveOnDemand reg; using (var stream = fileReader.GetFile("Registry.dat")) { if (stream is FileStream fileStream) { reg = new RegistryHiveOnDemand(fileStream.Name); } else { using var memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); memoryStream.Flush(); reg = new RegistryHiveOnDemand(memoryStream.ToArray(), "Registry.dat"); } } var key = reg.GetKey(@"root\registry\machine\software\caphyon\advanced installer\" + applicationId); if (key?.Values != null) { var psfDef = new PsfApplicationDescriptor(); foreach (var item in key.Values.Where(item => item.ValueName != null)) { switch (item.ValueName.ToLowerInvariant()) { case "path": psfDef.Executable = (item.ValueData ?? string.Empty).Replace("[{AppVPackageRoot}]\\", string.Empty); break; case "pathai": psfDef.Executable = (item.ValueData ?? string.Empty).Replace("[{AppVPackageRoot}]\\", string.Empty); break; case "workingdirectory": psfDef.WorkingDirectory = (item.ValueData ?? string.Empty).Replace("[{AppVPackageRoot}]\\", string.Empty); break; case "workingdirectoryai": psfDef.WorkingDirectory = (item.ValueData ?? string.Empty).Replace("[{AppVPackageRoot}]\\", string.Empty); break; case "args": psfDef.Arguments = item.ValueData; break; } } if (string.IsNullOrWhiteSpace(psfDef.Executable)) { psfDef.Executable = null; } else if (psfDef.Executable.StartsWith("[{", StringComparison.OrdinalIgnoreCase)) { var indexOfClosing = psfDef.Executable.IndexOf("}]", StringComparison.OrdinalIgnoreCase); if (indexOfClosing != -1) { var middlePart = psfDef.Executable.Substring(2, indexOfClosing - 2); var testedPath = "VFS\\" + middlePart + psfDef.Executable.Substring(indexOfClosing + 2); if (fileReader.FileExists(testedPath)) { // this is to make sure that a path like [{ProgramFilesX86}]\test is replaced to VFS\ProgramFilesX86\test if present psfDef.Executable = testedPath; } } } if (string.IsNullOrWhiteSpace(psfDef.WorkingDirectory)) { psfDef.WorkingDirectory = null; } if (string.IsNullOrWhiteSpace(psfDef.Arguments)) { psfDef.Arguments = null; } return(psfDef); } } } } var dir = Path.GetDirectoryName(originalEntryPoint); string configJson; if (string.IsNullOrEmpty(dir)) { configJson = "config.json"; } else { configJson = Path.Combine(dir, "config.json"); } if (fileReader.FileExists(configJson)) { using (var stream = fileReader.GetFile(configJson)) { using (var streamReader = new StreamReader(stream)) { return(this.Read(applicationId, originalEntryPoint, streamReader)); } } } return(null); }
private static async Task <AppxPackage> Translate(IAppxFileReader fileReader, AppxPackage package, CancellationToken cancellationToken) { var translationRequired = package.DisplayName?.StartsWith("ms-resource:") == true || package.PublisherDisplayName?.StartsWith("ms-resource:") == true || package.Description?.StartsWith("ms-resource:") == true || package.Applications.Any(a => a.DisplayName?.StartsWith("ms-resource:") == true) || package.Applications.Any(a => a.Description?.StartsWith("ms-resource:") == true); if (!translationRequired) { return(package); } string priFullPath = null; var cleanup = false; try { if (fileReader.FileExists("resources.pri")) { using (var stream = fileReader.GetFile("resources.pri")) { if (stream is FileStream fileStream) { priFullPath = fileStream.Name; } else { priFullPath = Path.GetTempFileName(); cleanup = true; using (var fs = File.OpenWrite(priFullPath)) { await stream.CopyToAsync(fs, cancellationToken).ConfigureAwait(false); await fs.FlushAsync(cancellationToken).ConfigureAwait(false); } } } package.DisplayName = StringLocalizer.Localize(priFullPath, package.Name, package.FullName, package.DisplayName); package.Description = StringLocalizer.Localize(priFullPath, package.Name, package.FullName, package.Description); package.PublisherDisplayName = StringLocalizer.Localize(priFullPath, package.Name, package.FullName, package.PublisherDisplayName); if (string.IsNullOrEmpty(package.DisplayName)) { package.DisplayName = package.Name; } if (string.IsNullOrEmpty(package.PublisherDisplayName)) { package.PublisherDisplayName = package.Publisher; } foreach (var app in package.Applications ?? Enumerable.Empty <AppxApplication>()) { app.DisplayName = StringLocalizer.Localize(priFullPath, app.Id, package.FullName, app.DisplayName); if (string.IsNullOrEmpty(app.DisplayName)) { app.DisplayName = app.Id; } app.Description = StringLocalizer.Localize(priFullPath, app.Id, package.FullName, app.Description); } } return(package); } finally { if (cleanup && File.Exists(priFullPath)) { File.Delete(priFullPath); } } }
private async Task <AppxPackage> ReadMsix(IAppxFileReader fileReader, string manifestFileName, CancellationToken cancellationToken = default) { using (var file = fileReader.GetFile(manifestFileName)) { var document = await XDocument.LoadAsync(file, LoadOptions.None, cancellationToken).ConfigureAwait(false); if (document.Root == null) { throw new FormatException("The manifest is malformed. There is no root element."); } var ns = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/foundation/windows10"); var ns2 = XNamespace.Get("http://schemas.microsoft.com/appx/2010/manifest"); var uap = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/uap/windows10"); var uap10 = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/uap/windows10/10"); var uap5 = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/uap/windows10/5"); var uap3 = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/uap/windows10/3"); var desktop10 = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/desktop/windows10"); var desktop6 = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"); var desktop2 = XNamespace.Get("http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"); var build = XNamespace.Get("http://schemas.microsoft.com/developer/appx/2015/build"); if (document.Root == null) { throw new FormatException("The manifest is malformed. The document root must be <Package /> element."); } if (document.Root.Name.LocalName != "Package") { throw new FormatException("The manifest is malformed. The document root must be <Package /> element."); } if (document.Root.Name.Namespace != ns && document.Root.Name.Namespace != ns2) { throw new FormatException("The manifest is malformed. The document root must be <Package /> element, belonging to a supported namespace."); } var nodePackage = document.Root; cancellationToken.ThrowIfCancellationRequested(); var nodeIdentity = nodePackage.Element(ns + "Identity") ?? nodePackage.Element(ns2 + "Identity"); cancellationToken.ThrowIfCancellationRequested(); var nodeProperties = nodePackage.Element(ns + "Properties") ?? nodePackage.Element(ns2 + "Properties"); cancellationToken.ThrowIfCancellationRequested(); var nodeApplicationsRoot = nodePackage.Element(ns + "Applications") ?? nodePackage.Element(ns2 + "Applications"); cancellationToken.ThrowIfCancellationRequested(); var nodeCapabilitiesRoot = nodePackage.Element(ns + "Capabilities") ?? nodePackage.Element(ns2 + "Capabilities"); cancellationToken.ThrowIfCancellationRequested(); var nodeDependenciesRoot = nodePackage.Element(ns + "Dependencies") ?? nodePackage.Element(ns2 + "Dependencies"); cancellationToken.ThrowIfCancellationRequested(); var nodePrerequisitesRoot = nodePackage.Element(ns + "Prerequisites") ?? nodePackage.Element(ns2 + "Prerequisites"); cancellationToken.ThrowIfCancellationRequested(); var nodeBuild = nodePackage.Element(build + "Metadata"); var appxPackage = new AppxPackage(); if (fileReader is IAppxDiskFileReader diskReader) { appxPackage.RootFolder = diskReader.RootDirectory; } else if (fileReader is ZipArchiveFileReaderAdapter zipArchiveReader) { appxPackage.RootFolder = Path.GetDirectoryName(zipArchiveReader.PackagePath); } cancellationToken.ThrowIfCancellationRequested(); if (nodeIdentity != null) { appxPackage.Name = nodeIdentity.Attribute("Name")?.Value; var procArch = nodeIdentity.Attribute("ProcessorArchitecture")?.Value; if (Enum.TryParse(typeof(AppxPackageArchitecture), procArch ?? string.Empty, true, out object parsedArchitecture) && parsedArchitecture != null) { appxPackage.ProcessorArchitecture = (AppxPackageArchitecture)parsedArchitecture; } else { appxPackage.ProcessorArchitecture = AppxPackageArchitecture.Neutral; } appxPackage.Publisher = nodeIdentity.Attribute("Publisher")?.Value; appxPackage.Version = nodeIdentity.Attribute("Version")?.Value; } cancellationToken.ThrowIfCancellationRequested(); if (nodeProperties != null) { foreach (var node in nodeProperties.Elements()) { switch (node.Name.LocalName) { case "Logo": var logo = node.Value; if (!string.IsNullOrEmpty(logo)) { using (var resourceStream = fileReader.GetResource(logo)) { if (resourceStream != null) { using (var memoryStream = new MemoryStream()) { await resourceStream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false); await memoryStream.FlushAsync(cancellationToken).ConfigureAwait(false); appxPackage.Logo = memoryStream.ToArray(); } } } } break; case "DisplayName": appxPackage.DisplayName = node.Value; break; case "PublisherDisplayName": appxPackage.PublisherDisplayName = node.Value; break; case "PackageIntegrity": var packageIntegrityContent = nodeProperties.Element(uap10 + "Content"); if (packageIntegrityContent != null) { appxPackage.PackageIntegrity = packageIntegrityContent.Attribute("Enforcement")?.Value == "on"; } break; case "Framework": appxPackage.IsFramework = string.Equals(node.Value ?? "false", "true", StringComparison.OrdinalIgnoreCase); break; case "Description": appxPackage.Description = node.Value; break; } } } cancellationToken.ThrowIfCancellationRequested(); appxPackage.PackageDependencies = new List <AppxPackageDependency>(); appxPackage.OperatingSystemDependencies = new List <AppxOperatingSystemDependency>(); appxPackage.MainPackages = new List <AppxMainPackageDependency>(); appxPackage.Applications = new List <AppxApplication>(); if (nodeApplicationsRoot != null) { foreach (var node in nodeApplicationsRoot.Elements().Where(x => x.Name.LocalName == "Application" && (x.Name.Namespace == ns || x.Name.Namespace == ns2))) { cancellationToken.ThrowIfCancellationRequested(); /* * <Application EntryPoint="SparklerApp.App" Executable="XD.exe" Id="App"> * <uap:VisualElements BackgroundColor="#2D001E" Description="Adobe XD" DisplayName="Adobe XD" Square150x150Logo="Assets\xd_med_tile.png" Square44x44Logo="Assets\xd_app_list_icon.png"> * <uap:DefaultTile Square310x310Logo="Assets\xd_large_tile.png" Square71x71Logo="Assets\xd_small_tile.png" Wide310x150Logo="Assets\xd_wide_tile.png"> * <uap:ShowNameOnTiles> * <uap:ShowOn Tile="square150x150Logo" /> * <uap:ShowOn Tile="wide310x150Logo" /> * <uap:ShowOn Tile="square310x310Logo" /> * </uap:ShowNameOnTiles> * </uap:DefaultTile> * <uap:SplashScreen BackgroundColor="#FFFFFF" Image="Assets\xd_splash.png" /> * </uap:VisualElements> * * <Application Id="RayEval" Executable="PsfLauncher32.exe" EntryPoint="Windows.FullTrustApplication"> * <uap:VisualElements DisplayName="RayEval" Description="RayEval Raynet GmbH" BackgroundColor="transparent" * Square150x150Logo="Assets\Square150x150Logo.scale-100.png" Square44x44Logo="Assets\Square44x44Logo.scale-100.png"> * <uap:DefaultTile Wide310x150Logo="Assets\Square310x150Logo.scale-100.png" Square310x310Logo="Assets\Square310x310Logo.scale-100.png" Square71x71Logo="Assets\Square71x71Logo.scale-100.png" /> * </uap:VisualElements> * <Extensions /> * </Application> */ var appxApplication = new AppxApplication { EntryPoint = node.Attribute("EntryPoint")?.Value, StartPage = node.Attribute("StartPage")?.Value, Executable = node.Attribute("Executable")?.Value, Id = node.Attribute("Id")?.Value, Extensions = new List <AppxExtension>() }; /* * <Extensions><desktop6:Extension Category="windows.service" Executable="VFS\ProgramFilesX86\RayPackStudio\FloatingLicenseServer\FloatingLicenseServer.exe" EntryPoint="Windows.FullTrustApplication"><desktop6:Service Name="PkgSuiteFloatingLicenseServer" StartupType="auto" StartAccount="networkService" /></desktop6:Extension></Extensions> */ var nodeExtensions = node.Elements().FirstOrDefault(e => e.Name.LocalName == "Extensions"); if (nodeExtensions != null) { foreach (var extension in nodeExtensions.Elements().Where(e => e.Name.LocalName == "Extension" && (e.Name.Namespace == ns || e.Name.Namespace == ns2 || e.Name.Namespace == desktop6 || e.Name.Namespace == desktop2 || e.Name.Namespace == uap5 || e.Name.Namespace == uap3))) { cancellationToken.ThrowIfCancellationRequested(); var category = extension.Attribute("Category")?.Value; switch (category) { case "windows.appExecutionAlias": var aliasNode = extension.Element(uap3 + "AppExecutionAlias") ?? extension.Element(uap5 + "AppExecutionAlias"); if (aliasNode != null) { var desktopExecAliases = aliasNode.Elements(desktop10 + "ExecutionAlias").Concat(aliasNode.Elements(uap5 + "ExecutionAlias")); foreach (var desktopExecAlias in desktopExecAliases) { if (appxApplication.ExecutionAlias == null) { appxApplication.ExecutionAlias = new List <string>(); } appxApplication.ExecutionAlias.Add(desktopExecAlias.Attribute("Alias")?.Value); } } break; case "windows.service": var serviceNode = extension.Element(desktop6 + "Service"); if (serviceNode == null) { continue; } var service = new AppxService { Category = "windows.service" }; service.EntryPoint = extension.Attribute("EntryPoint")?.Value; service.Executable = extension.Attribute("Executable")?.Value; service.Name = extension.Attribute("Name")?.Value; service.StartAccount = extension.Attribute("StartAccount")?.Value; service.StartupType = extension.Attribute("StartupType")?.Value; appxApplication.Extensions.Add(service); break; } } } var visualElements = node.Elements().FirstOrDefault(e => e.Name.LocalName == "VisualElements"); if (visualElements != null) { cancellationToken.ThrowIfCancellationRequested(); appxApplication.Description = visualElements.Attribute("Description")?.Value; appxApplication.DisplayName = visualElements.Attribute("DisplayName")?.Value; appxApplication.BackgroundColor = visualElements.Attribute("BackgroundColor")?.Value; appxApplication.Square150x150Logo = visualElements.Attribute("Square150x150Logo")?.Value; appxApplication.Square44x44Logo = visualElements.Attribute("Square44x44Logo")?.Value; appxApplication.Visible = visualElements.Attribute("AppListEntry")?.Value != "none"; var defaultTile = visualElements.Element(uap + "DefaultTile"); if (defaultTile != null) { appxApplication.Wide310x150Logo = defaultTile.Attribute("Wide310x150Logo")?.Value; appxApplication.Square310x310Logo = defaultTile.Attribute("Square310x310Logo")?.Value; appxApplication.Square71x71Logo = defaultTile.Attribute("Square71x71Logo")?.Value; appxApplication.ShortName = defaultTile.Attribute("ShortName")?.Value; } var logo = appxApplication.Square44x44Logo ?? appxApplication.Square30x30Logo ?? appxApplication.Square71x71Logo ?? appxApplication.Square150x150Logo; if (logo == null) { appxApplication.Logo = appxPackage.Logo; } else { using (var stream = fileReader.GetResource(appxApplication.Square44x44Logo) ?? fileReader.GetResource(appxApplication.Square30x30Logo) ?? fileReader.GetResource(appxApplication.Square71x71Logo) ?? fileReader.GetResource(appxApplication.Square150x150Logo)) { if (stream != null) { var bytes = new byte[stream.Length]; await stream.ReadAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); appxApplication.Logo = bytes; } else { appxApplication.Logo = appxPackage.Logo; } } } } appxPackage.Applications.Add(appxApplication); } var psfApps = appxPackage.Applications.Where(a => PackageTypeConverter.GetPackageTypeFrom(a.EntryPoint, a.Executable, a.StartPage, appxPackage.IsFramework) == MsixPackageType.BridgePsf).ToArray(); if (psfApps.Any()) { foreach (var psfApp in psfApps) { cancellationToken.ThrowIfCancellationRequested(); psfApp.Psf = this.PsfReader.Read(psfApp.Id, psfApp.Executable, fileReader); } } } if (nodeDependenciesRoot != null) { var dependencies = nodeDependenciesRoot.Elements(); if (dependencies != null) { foreach (var node in dependencies) { switch (node.Name.LocalName) { case "MainPackageDependency": var modName = node.Attribute("Name")?.Value; var appxModPackDependency = new AppxMainPackageDependency { Name = modName, }; appxPackage.MainPackages.Add(appxModPackDependency); break; case "TargetDeviceFamily": { /* * <TargetDeviceFamily MaxVersionTested="10.0.15063.0" MinVersion="10.0.15063.0" Name="Windows.Universal" /> */ var minVersion = node.Attribute("MinVersion")?.Value; var maxVersion = node.Attribute("MaxVersionTested")?.Value; var name = node.Attribute("Name")?.Value; appxPackage.OperatingSystemDependencies.Add(new AppxOperatingSystemDependency { Minimum = WindowsNames.GetOperatingSystemFromNameAndVersion(name, minVersion), Tested = WindowsNames.GetOperatingSystemFromNameAndVersion(name, maxVersion), }); break; } case "PackageDependency": { /* * <PackageDependency MinVersion="1.4.24201.0" Name="Microsoft.NET.Native.Runtime.1.4" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" /> */ var minVersion = node.Attribute("MinVersion")?.Value; var name = node.Attribute("Name")?.Value; var publisher = node.Attribute("Publisher")?.Value; var appxDependency = new AppxPackageDependency { Publisher = publisher, Name = name, Version = minVersion }; appxPackage.PackageDependencies.Add(appxDependency); break; } } } } } if (nodePrerequisitesRoot != null) { var min = nodePrerequisitesRoot.Element(ns2 + "OSMinVersion")?.Value; var max = nodePrerequisitesRoot.Element(ns2 + "OSMaxVersionTested")?.Value; appxPackage.OperatingSystemDependencies.Add(new AppxOperatingSystemDependency { Minimum = min == null ? null : WindowsNames.GetOperatingSystemFromNameAndVersion("Windows.Desktop", min), Tested = max == null ? null : WindowsNames.GetOperatingSystemFromNameAndVersion("Windows.Desktop", max), }); } if (nodeBuild != null) { var buildKeyValues = new Dictionary <string, string>(); foreach (var buildNode in nodeBuild.Elements(build + "Item")) { var attrName = buildNode.Attribute("Name")?.Value; if (attrName == null) { continue; } var attrVersion = buildNode.Attribute("Version")?.Value; if (attrVersion == null) { attrVersion = buildNode.Attribute("Value")?.Value; if (attrVersion == null) { continue; } } buildKeyValues[attrName] = attrVersion; } var appDetector = new AuthoringAppDetector(fileReader); if (appDetector.TryDetectAny(buildKeyValues, out var buildInfo)) { appxPackage.BuildInfo = buildInfo; } } appxPackage.FamilyName = AppxPackaging.GetPackageFamilyName(appxPackage.Name, appxPackage.Publisher); appxPackage.FullName = AppxPackaging.GetPackageFullName(appxPackage.Name, appxPackage.Publisher, appxPackage.ProcessorArchitecture, appxPackage.Version, appxPackage.ResourceId); appxPackage.Capabilities = this.GetCapabilities(nodeCapabilitiesRoot); var pkgManager = new PackageManager(); var pkg = pkgManager.FindPackageForUser(string.Empty, appxPackage.FullName); if (pkg == null && appxPackage.ResourceId == null) { appxPackage.FullName = AppxPackaging.GetPackageFullName(appxPackage.Name, appxPackage.Publisher, appxPackage.ProcessorArchitecture, appxPackage.Version, "neutral"); pkg = pkgManager.FindPackageForUser(string.Empty, appxPackage.FullName); } string manifestFilePath; if (pkg?.InstalledLocation != null) { manifestFilePath = Path.Combine(pkg.InstalledLocation.Path, FileConstants.AppxManifestFile); } else if (fileReader is IAppxDiskFileReader appxDiskReader) { manifestFilePath = Path.Combine(appxDiskReader.RootDirectory, manifestFileName); } else { manifestFilePath = manifestFileName; } if (pkg == null) { appxPackage.Source = new NotInstalledSource(); } else if (pkg.SignatureKind == PackageSignatureKind.System) { appxPackage.Source = new SystemSource(manifestFilePath); } else if (pkg.SignatureKind == PackageSignatureKind.None || pkg.IsDevelopmentMode) { appxPackage.Source = new DeveloperSource(Path.Combine(appxPackage.RootFolder, manifestFileName)); } else if (pkg.SignatureKind == PackageSignatureKind.Store) { appxPackage.Source = new StorePackageSource(appxPackage.FamilyName, Path.GetDirectoryName(manifestFilePath)); } else { var appInstaller = pkg.GetAppInstallerInfo(); if (appInstaller != null) { appxPackage.Source = new AppInstallerPackageSource(appInstaller.Uri, Path.GetDirectoryName(manifestFilePath)); } } if (appxPackage.Source == null) { appxPackage.Source = new StandardSource(manifestFilePath); } return(await Translate(fileReader, appxPackage, cancellationToken).ConfigureAwait(false)); } }