예제 #1
0
        public static async Task <AppxPackage> ToAppxPackage(this InstalledPackage pkg, CancellationToken cancellationToken = default)
        {
            if (pkg.InstallLocation == null)
            {
                return(null);
            }

            var manifestReader = new AppxManifestReader();

            IAppxFileReader reader;

            if (pkg.ManifestLocation == null || !File.Exists(pkg.ManifestLocation))
            {
                reader = new PackageIdentityFileReaderAdapter(PackageContext.CurrentUser, pkg.PackageId);
            }
            else
            {
                reader = new FileInfoFileReaderAdapter(pkg.ManifestLocation);
            }

            using (reader)
            {
                return(await manifestReader.Read(reader, cancellationToken).ConfigureAwait(false));
            }
        }
예제 #2
0
        // 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);
        }
        public async Task RunToolInContext(InstalledPackage package, string toolPath, string arguments, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            if (toolPath == null)
            {
                throw new ArgumentNullException(nameof(toolPath));
            }

            using (IAppxFileReader reader = new FileInfoFileReaderAdapter(package.ManifestLocation))
            {
                var maniReader = new AppxManifestReader();
                var manifest   = await maniReader.Read(reader, cancellationToken).ConfigureAwait(false);

                if (!manifest.Applications.Any())
                {
                    throw new InvalidOperationException("Cannot execute a command in this package context. The package does not have any applications defined.");
                }

                await RunToolInContext(package.PackageFamilyName, manifest.Applications[0].Id, toolPath, arguments, cancellationToken, progress).ConfigureAwait(false);
            }
        }
예제 #4
0
 public Fixture()
 {
     FileSystem = new FakeFileSystem(new FakeEnvironment(PlatformFamily.Windows));
     Reader     = new AppxManifestReader(
         FileSystem,
         new FakeNativeStreamProvider(FileSystem),
         Substitute.For <IJarvisLog>());
 }
        private static async Task AssertPackagesUpgradable(string package1Path, string package2Path, bool ignoreVersionCheck = false)
        {
            if (string.IsNullOrEmpty(package1Path))
            {
                throw new ArgumentNullException(nameof(package1Path));
            }

            if (string.IsNullOrEmpty(package2Path))
            {
                throw new ArgumentNullException(nameof(package2Path));
            }

            var    manifestReader = new AppxManifestReader();
            string packageFamily1, packageFamily2, version1, version2, name1, name2;

            try
            {
                using var fileReader1 = FileReaderFactory.CreateFileReader(package1Path);
                var file1 = await manifestReader.Read(fileReader1).ConfigureAwait(false);

                packageFamily1 = file1.FamilyName;
                version1       = file1.Version;
                name1          = file1.DisplayName;
            }
            catch (Exception e)
            {
                throw new UpdateImpactException($"Could not read the package. File {package1Path} has invalid or unsupported format.", UpgradeImpactError.WrongPackageFormat, e);
            }

            try
            {
                using var fileReader2 = FileReaderFactory.CreateFileReader(package2Path);
                var file2 = await manifestReader.Read(fileReader2).ConfigureAwait(false);

                packageFamily2 = file2.FamilyName;
                version2       = file2.Version;
                name2          = file2.DisplayName;
            }
            catch (Exception e)
            {
                throw new UpdateImpactException($"Could not read the package. File {package2Path} has invalid or unsupported format.", UpgradeImpactError.WrongPackageFormat, e);
            }

            if (!string.Equals(packageFamily1, packageFamily2))
            {
                throw new UpdateImpactException($"Package '{name2}' cannot upgrade the package '{name1}' because they do not share the same family name.", UpgradeImpactError.WrongFamilyName);
            }

            if (ignoreVersionCheck)
            {
                return;
            }

            if (Version.Parse(version2) <= Version.Parse(version1))
            {
                throw new UpdateImpactException($"Package '{name2}' version '{version2}' cannot update the package '{name1}' version '{version1}'. The version of the upgrade package must be higher than '{version1}'.", UpgradeImpactError.WrongPackageVersion);
            }
        }
예제 #6
0
        public async Task <AppxPackage> GetByManifestPath(string manifestPath, PackageFindMode mode = PackageFindMode.CurrentUser, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using IAppxFileReader reader = new FileInfoFileReaderAdapter(manifestPath);
            var manifestReader = new AppxManifestReader();
            // ReSharper disable once AccessToDisposedClosure
            var package = await Task.Run(() => manifestReader.Read(reader, true, cancellationToken), cancellationToken).ConfigureAwait(false);

            return(package);
        }
예제 #7
0
        public async Task <AppxPackage> GetByIdentity(string packageName, PackageFindMode mode = PackageFindMode.CurrentUser, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using var reader = new PackageIdentityFileReaderAdapter(mode == PackageFindMode.CurrentUser ? PackageContext.CurrentUser : PackageContext.AllUsers, packageName);
            var manifestReader = new AppxManifestReader();
            // ReSharper disable once AccessToDisposedClosure
            var package = await Task.Run(() => manifestReader.Read(reader, true, cancellationToken), cancellationToken).ConfigureAwait(false);

            return(package);
        }
예제 #8
0
        public async Task <DependencyGraph> GetGraph(string initialPackage, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null)
        {
            progress?.Report(new ProgressData(0, $"Reading {Path.GetFileName(initialPackage)}..."));

            var reader = new AppxManifestReader();

            using var fileReader = FileReaderFactory.CreateFileReader(initialPackage);
            var pkg = await reader.Read(fileReader, cancellationToken).ConfigureAwait(false);

            return(await this.GetGraph(pkg, cancellationToken, progress).ConfigureAwait(false));
        }
        public async Task <bool> IsInstalled(string manifestPath, PackageFindMode mode = PackageFindMode.CurrentUser, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            PackageFindMode actualMode = mode;

            if (actualMode == PackageFindMode.Auto)
            {
                var isAdmin = await UserHelper.IsAdministratorAsync(cancellationToken).ConfigureAwait(false);

                if (isAdmin)
                {
                    actualMode = PackageFindMode.AllUsers;
                }
                else
                {
                    actualMode = PackageFindMode.CurrentUser;
                }
            }

            string pkgFullName;

            using (var src = FileReaderFactory.CreateFileReader(manifestPath))
            {
                var manifestReader = new AppxManifestReader();
                var parsed         = await manifestReader.Read(src, false, cancellationToken).ConfigureAwait(false);

                pkgFullName = parsed.FullName;
            }

            switch (actualMode)
            {
            case PackageFindMode.CurrentUser:
                var pkg = await Task.Run(
                    () => PackageManagerWrapper.Instance.FindPackageForUser(string.Empty, pkgFullName),
                    cancellationToken).ConfigureAwait(false);

                return(pkg != null);

            case PackageFindMode.AllUsers:
                var pkgAllUsers = await Task.Run(
                    () => PackageManagerWrapper.Instance.FindPackage(pkgFullName),
                    cancellationToken).ConfigureAwait(false);

                return(pkgAllUsers != null);

            default:
                throw new NotSupportedException();
            }
        }
예제 #10
0
        public void ReadFromFile()
        {
            var file = Path.Combine("Resources", "ConEmuPack-O2004-M1220.603-P380-F_19.1.8.0_x64__xwfzvwzp69w2e.msix");

            using (IAppxFileReader appxFileReader = new ZipArchiveFileReaderAdapter(file))
            {
                var manifestReader = new AppxManifestReader();
                var manifest       = manifestReader.Read(appxFileReader).GetAwaiter().GetResult();

                var app  = manifest.Applications[0];
                var type = PackageTypeConverter.GetPackageTypeFrom(app.EntryPoint, app.Executable, app.StartPage, manifest.IsFramework);
                Assert.AreEqual(MsixPackageType.BridgePsf, type);

                Assert.AreEqual(app.Psf.Executable, "VFS\\AppVPackageDrive\\ConEmuPack\\ConEmu64.exe");
                Assert.AreEqual("VFS\\AppVPackageDrive\\ConEmuPack\\PsfLauncher1.exe", app.Executable);
            }
        }
예제 #11
0
        private void SourcePathOnValueChanged(object sender, ValueChangedEventArgs e)
        {
            try
            {
                var ext = Path.GetExtension((string)e.NewValue);
                if (string.Equals(".msix", ext))
                {
                    using (IAppxFileReader reader = new ZipArchiveFileReaderAdapter((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;
                    }
                }
                else
                {
                    using (IAppxFileReader reader = new FileInfoFileReaderAdapter((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);
            }
        }
예제 #12
0
        public async Task RunToolInContext(InstalledPackage package, string toolPath, string arguments = null, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            using IAppxFileReader reader = new FileInfoFileReaderAdapter(package.ManifestLocation);

            var maniReader = new AppxManifestReader();
            var manifest   = await maniReader.Read(reader, cancellationToken).ConfigureAwait(false);

            if (!manifest.Applications.Any())
            {
                throw new InvalidOperationException("Cannot start tool on a package without applications.");
            }

            var proxyObject = new RunToolInContextDto
            {
                PackageFamilyName = package.PackageFamilyName,
                AppId             = manifest.Applications[0].Id,
                Arguments         = arguments,
                ToolPath          = toolPath
            };

            await this.client.Invoke(proxyObject, cancellationToken, progress).ConfigureAwait(false);
        }
예제 #13
0
        private static async Task <string[]> GetEntryPoints(string manifestLocation)
        {
            if (!File.Exists(manifestLocation))
            {
                return(new string[0]);
            }

            var reader = new AppxManifestReader();

            using (IAppxFileReader appxSource = new FileInfoFileReaderAdapter(manifestLocation))
            {
                var appxPackage = await reader.Read(appxSource).ConfigureAwait(false);

                return(appxPackage.Applications.Select(app =>
                {
                    if (string.IsNullOrEmpty(app.Id))
                    {
                        return @"shell:appsFolder\" + appxPackage.FamilyName;
                    }

                    return @"shell:appsFolder\" + appxPackage.FamilyName + "!" + app.Id;
                }).ToArray());
            }
        }
예제 #14
0
        public async Task GenerateLogic(string packagePath, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null)
        {
            var reader = new AppxManifestReader();

            using (var fileReader = FileReaderFactory.CreateFileReader(packagePath))
            {
                this.Package = await reader.Read(fileReader, false, cancellationToken).ConfigureAwait(false);
            }

            var graph   = new DependencyBidirectionalGraph();
            var mapping = await this.dependencyMapper.GetGraph(this.Package, cancellationToken, progress).ConfigureAwait(false);

            var dict = new Dictionary <GraphElement, DependencyVertex>();

            foreach (var item in mapping.Elements)
            {
                DependencyVertex dv;

                if (item is RootGraphElement root)
                {
                    dv = new RootDependencyVertex(root.Package);
                }
                else if (item is PackageGraphElement appxPackage)
                {
                    dv = new InstalledDependencyVertex(appxPackage.Package);
                }
                else if (item is OperatingSystemGraphElement ose)
                {
                    dv = new SystemDependencyVertex(ose.MaxRequiredCaption);
                }
                else
                {
                    dv = new DependencyVertex();

                    if (item is MissingPackageGraphElement mpe)
                    {
                        dv.Text = mpe.PackageName;
                    }
                    else
                    {
                        dv.Text = "?";
                    }
                }

                dv.ID = item.Id;

                graph.AddVertex(dv);
                dict[item] = dv;
            }

            foreach (var relation in mapping.Relations)
            {
                graph.AddEdge(new DependencyEdge()
                {
                    Source = dict[relation.Left],
                    Target = dict[relation.Right],
                    Text   = relation.RelationDescription
                });
            }

            var logicCore = new DependencyLogicCore();

            logicCore.Graph = graph;

            logicCore.DefaultLayoutAlgorithm       = LayoutAlgorithmTypeEnum.KK;
            logicCore.DefaultLayoutAlgorithmParams = logicCore.AlgorithmFactory.CreateLayoutParameters(LayoutAlgorithmTypeEnum.KK);
            ((KKLayoutParameters)logicCore.DefaultLayoutAlgorithmParams).MaxIterations = 100;

            logicCore.DefaultOverlapRemovalAlgorithm       = OverlapRemovalAlgorithmTypeEnum.FSA;
            logicCore.DefaultOverlapRemovalAlgorithmParams = logicCore.AlgorithmFactory.CreateOverlapRemovalParameters(OverlapRemovalAlgorithmTypeEnum.FSA);
            ((OverlapRemovalParameters)logicCore.DefaultOverlapRemovalAlgorithmParams).HorizontalGap = 50;
            ((OverlapRemovalParameters)logicCore.DefaultOverlapRemovalAlgorithmParams).VerticalGap   = 50;

            logicCore.DefaultEdgeRoutingAlgorithm = EdgeRoutingAlgorithmTypeEnum.SimpleER;
            logicCore.AsyncAlgorithmCompute       = false;
            logicCore.EdgeCurvingEnabled          = true;

            this.LogicCore = logicCore;
        }
예제 #15
0
        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);
        }
예제 #16
0
 public UwpIndexSource(AppxManifestReader reader, IFileSystem fileSystem, IJarvisLog log)
 {
     _reader     = reader;
     _fileSystem = fileSystem;
     _log        = log;
 }
예제 #17
0
        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 ComparePackages(bool ignorePackageVersionError = false)
        {
            this.IsValidated = true;

            if (!this.IsValid)
            {
                this.interactionService.ShowError(this.ValidationMessage, InteractionResult.OK, "Missing values");
                return;
            }

            this.Progress.Progress  = -1;
            this.Progress.IsLoading = true;
            try
            {
                using var cts = new CancellationTokenSource();
                var manifestParser = new AppxManifestReader();
                using var file1 = FileReaderFactory.CreateFileReader(this.Path1.CurrentValue);
                using var file2 = FileReaderFactory.CreateFileReader(this.Path2.CurrentValue);

                var task1 = manifestParser.Read(file1, cts.Token);
                var task2 = manifestParser.Read(file2, cts.Token);

                var progress    = new Progress <ProgressData>();
                var taskCompare = this.updateImpactAnalyzer.Analyze(this.Path1.CurrentValue, this.Path2.CurrentValue, ignorePackageVersionError, cts.Token, progress);

                var taskComplete = Task.WhenAll(task1, task2, taskCompare);

                this.Progress.MonitorProgress(taskComplete, cts, progress);
                await taskComplete.ConfigureAwait(false);

                var result = await taskCompare.ConfigureAwait(false);

                this.Results.CurrentValue    = new ComparisonViewModel(result);
                this.OldPackage.CurrentValue = new PackageContentDetailsViewModel(await task1.ConfigureAwait(false), this.Path1.CurrentValue);
                this.NewPackage.CurrentValue = new PackageContentDetailsViewModel(await task2.ConfigureAwait(false), this.Path2.CurrentValue);
            }
            catch (UpdateImpactException updateImpactException)
            {
                switch (updateImpactException.ErrorType)
                {
                case UpgradeImpactError.WrongPackageVersion:
                    if (ignorePackageVersionError)
                    {
                        this.interactionService.ShowError(updateImpactException.Message);
                        return;
                    }

                    var result = this.interactionService.ShowError(updateImpactException.Message + "\r\nPress Retry to ignore the version check and compare the packages anyway.", InteractionResult.Retry | InteractionResult.Close, "Invalid versions");
                    if (result == InteractionResult.Retry)
                    {
                        await this.ComparePackages(true).ConfigureAwait(false);
                    }

                    break;

                default:
                    this.interactionService.ShowError(updateImpactException.Message);
                    return;
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception e)
            {
                this.interactionService.ShowError("Could not compare selected packages. " + e.Message, e);
            }
            finally
            {
                this.Progress.IsLoading = false;
            }
        }
예제 #19
0
        private async Task <YamlDefinition> CreateFromMsix(string filePath, CancellationToken cancellationToken = default)
        {
            var yamlDefinition = new YamlDefinition()
            {
                Installers = new List <YamlInstaller>
                {
                    new YamlInstaller
                    {
                        Scope         = YamlScope.user,
                        InstallerType = YamlInstallerType.msix
                    }
                }
            };

            IAppxFileReader reader;

            if (filePath.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
            {
                reader = new FileInfoFileReaderAdapter(filePath);
            }
            else
            {
                reader = new ZipArchiveFileReaderAdapter(filePath);

                try
                {
                    yamlDefinition.Installers[0].SignatureSha256 = await this.CalculateSignatureHashAsync(new FileInfo(filePath), cancellationToken).ConfigureAwait(false);
                }
                catch (ArgumentException)
                {
                }
            }

            using (reader)
            {
                var manifestReader = new AppxManifestReader();
                var details        = await manifestReader.Read(reader, cancellationToken).ConfigureAwait(false);

                yamlDefinition.Name        = details.DisplayName;
                yamlDefinition.Publisher   = details.PublisherDisplayName;
                yamlDefinition.Version     = details.Version;
                yamlDefinition.Description = details.Description;

                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));

                    if (!string.IsNullOrEmpty(candidateForAppMoniker))
                    {
                        yamlDefinition.AppMoniker = candidateForAppMoniker.Substring(0, candidateForAppMoniker.Length - ".exe".Length).Split('\\', '/').Last();
                    }
                }

                switch (details.ProcessorArchitecture)
                {
                case AppxPackageArchitecture.Arm:
                    yamlDefinition.Installers[0].Arch = YamlArchitecture.arm;
                    break;

                case AppxPackageArchitecture.Neutral:
                    yamlDefinition.Installers[0].Arch = YamlArchitecture.Neutral;
                    break;

                case AppxPackageArchitecture.Arm64:
                    yamlDefinition.Installers[0].Arch = YamlArchitecture.arm64;
                    break;

                case AppxPackageArchitecture.x86:
                    yamlDefinition.Installers[0].Arch = YamlArchitecture.x86;
                    break;

                case AppxPackageArchitecture.x64:
                    yamlDefinition.Installers[0].Arch = YamlArchitecture.x64;
                    break;
                }
            }

            return(yamlDefinition);
        }
예제 #20
0
        private async Task <IList <AppxPackage> > GetConsideredPackages(AppxPackage startPackage, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            var progressForGettingPackages = new RangeProgress(progress, 0, 70);
            var progressForGettingAddOns   = new RangeProgress(progress, 70, 90);
            var progressForCalculation     = new RangeProgress(progress, 90, 100);

            var manager = await this.packageManager.GetProxyFor(SelfElevationLevel.HighestAvailable, cancellationToken).ConfigureAwait(false);

            var allPackages = await manager.GetInstalledPackages(PackageFindMode.Auto, cancellationToken, progressForGettingPackages).ConfigureAwait(false);

            var consideredPackages = new List <AppxPackage> {
                startPackage
            };
            var addOnPackages = new List <AppxPackage>();

            var manifestReader = new AppxManifestReader();

            progressForGettingAddOns.Report(new ProgressData(0, "Reading optional packages..."));
            foreach (var addOnPackage in allPackages.Where(installedPackage => installedPackage.IsOptional))
            {
                using var fileReader = FileReaderFactory.CreateFileReader(addOnPackage.ManifestLocation);
                addOnPackages.Add(await manifestReader.Read(fileReader, false, cancellationToken).ConfigureAwait(false));
            }

            progressForCalculation.Report(new ProgressData(0, "Reading relations..."));
            for (var i = 0; i < consideredPackages.Count; i++)
            {
                var currentPkg = consideredPackages[i];

                var matchingAddOns = addOnPackages.Where(addOnPackage => addOnPackage.MainPackages.Any(dep => dep.Name == currentPkg.Name));
                foreach (var matchingAddOn in matchingAddOns)
                {
                    if (consideredPackages.Any(existing => existing.Publisher == matchingAddOn.Publisher && existing.Name == matchingAddOn.Name))
                    {
                        // we have already processes this package
                        continue;
                    }

                    consideredPackages.Add(matchingAddOn);
                }

                foreach (var dependency in currentPkg.PackageDependencies)
                {
                    if (consideredPackages.Any(existing => existing.Publisher == dependency.Publisher && existing.Name == dependency.Name))
                    {
                        // we have already processes this package
                        continue;
                    }

                    var candidate = allPackages.FirstOrDefault(installedPackage => installedPackage.Name == dependency.Name && installedPackage.Publisher == dependency.Publisher && installedPackage.Version >= Version.Parse(dependency.Version));

                    if (candidate != null)
                    {
                        using var fileReader = FileReaderFactory.CreateFileReader(candidate.ManifestLocation);
                        consideredPackages.Add(await manifestReader.Read(fileReader, false, cancellationToken).ConfigureAwait(false));
                    }
                }

                foreach (var dependency in currentPkg.MainPackages)
                {
                    if (consideredPackages.Any(existing => existing.Name == dependency.Name))
                    {
                        // we have already processes this package
                        continue;
                    }

                    var candidate = allPackages.FirstOrDefault(installedPackage => installedPackage.Name == dependency.Name);

                    if (candidate != null)
                    {
                        using var fileReader = FileReaderFactory.CreateFileReader(candidate.ManifestLocation);
                        consideredPackages.Add(await manifestReader.Read(fileReader, false, cancellationToken).ConfigureAwait(false));
                    }
                }
            }

            return(consideredPackages);
        }