Exemplo n.º 1
0
        public override bool ProcessRecordAsync()
        {
            // keep track of what package names the user asked for.
            if (!Name.IsNullOrEmpty())
            {
                foreach (var name in Name)
                {
                    _namesProcessed.GetOrAdd(name, () => false);
                }
            }

            var requests = (Name.IsNullOrEmpty() ?

                            // if the user didn't specify any names
                            SelectedProviders.Select(pv => new {
                query = "?",
                packages = pv.GetInstalledPackages("", this.ProviderSpecific(pv)).CancelWhen(_cancellationEvent.Token)
            }) :

                            // if the user specified a name,
                            SelectedProviders.SelectMany(pv => {
                // for a given provider, if we get an error, we want just that provider to stop.
                var host = this.ProviderSpecific(pv);

                return(Name.Select(name => new {
                    query = name,
                    packages = pv.GetInstalledPackages(name, host).CancelWhen(_cancellationEvent.Token)
                }));
            })).ToArray();

            while (WaitForActivity(requests.Select(each => each.packages)))
            {
                // keep processing while any of the the queries is still going.

                foreach (var result in requests.Where(each => each.packages.HasData))
                {
                    // look only at requests that have data waiting.

                    foreach (var package in result.packages.GetConsumingEnumerable())
                    {
                        // process the results for that set.

                        if (IsPackageInVersionRange(package))
                        {
                            // it only counts if the package is in the range we're looking for.

                            // mark down that we found something for that query
                            _namesProcessed.AddOrSet(result.query, true);

                            ProcessPackage(result.query, package);
                        }
                    }
                }

                // just work with whatever is not yet consumed
                requests = requests.FilterWithFinalizer(each => each.packages.IsConsumed, each => each.packages.Dispose()).ToArray();
            }
            return(true);
        }
Exemplo n.º 2
0
        public override bool ProcessRecordAsync()
        {
            // keep track of what package names the user asked for.
            if (!Name.IsNullOrEmpty())
            {
                foreach (var name in Name)
                {
                    _namesProcessed.GetOrAdd(name, () => false);
                }
            }

            var requests = (Name.IsNullOrEmpty() ?

                            // if the user didn't specify any names
                            SelectedProviders.Select(pv => new {
                query = "?",
                packages = pv.GetInstalledPackages("", RequiredVersion, MinimumVersion, MaximumVersion, this.ProviderSpecific(pv)).CancelWhen(CancellationEvent.Token)
            }) :

                            // if the user specified a name,
                            SelectedProviders.SelectMany(pv => {
                // for a given provider, if we get an error, we want just that provider to stop.
                var host = this.ProviderSpecific(pv);

                return(Name.Select(name => new {
                    query = name,
                    packages = pv.GetInstalledPackages(name, RequiredVersion, MinimumVersion, MaximumVersion, host).CancelWhen(CancellationEvent.Token)
                }));
            })).ToArray();

            var potentialPackagesToProcess = new System.Collections.ObjectModel.Collection <SoftwareIdentity>();

            while (WaitForActivity(requests.Select(each => each.packages)))
            {
                // keep processing while any of the the queries is still going.
                foreach (var result in requests.Where(each => each.packages.HasData))
                {
                    // look only at requests that have data waiting.

                    foreach (var package in result.packages.GetConsumingEnumerable())
                    {
                        // process the results for that set.

                        if (IsPackageInVersionRange(package))
                        {
                            // it only counts if the package is in the range we're looking for.

                            // mark down that we found something for that query
                            _namesProcessed.AddOrSet(result.query, true);
                            potentialPackagesToProcess.Add(package);
                        }
                    }
                }
                // just work with whatever is not yet consumed
                requests = requests.FilterWithFinalizer(each => each.packages.IsConsumed, each => each.packages.Dispose()).ToArray();
            } // end of WaitForActivity()

            // post processing the potential packages as we have to display only
            // 1 package per name (note multiple versions of the same package may be installed)
            // In general, it is good practice to show only the latest one.
            foreach (var potentialPackage in from p in potentialPackagesToProcess
                     group p by p.Name
                     into grouping
                     select grouping.OrderByDescending(pp => pp, SoftwareIdentityVersionComparer.Instance).First()
                     )
            {
                ProcessPackage(potentialPackage.CanonicalId, potentialPackage);
            }

            return(true);
        }
Exemplo n.º 3
0
        public override bool ProcessRecordAsync()
        {
            ValidateVersion(RequiredVersion);
            ValidateVersion(MinimumVersion);
            ValidateVersion(MaximumVersion);

            // If AllVersions is specified, make sure other version parameters are not supplied
            if (AllVersions.IsPresent)
            {
                if ((!string.IsNullOrWhiteSpace(RequiredVersion)) || (!string.IsNullOrWhiteSpace(MinimumVersion)) || (!string.IsNullOrWhiteSpace(MaximumVersion)))
                {
                    Error(Constants.Errors.AllVersionsCannotBeUsedWithOtherVersionParameters);
                }
            }

            // Cannot have Max/Min version parameters with RequiredVersion
            if (RequiredVersion != null)
            {
                if ((!string.IsNullOrWhiteSpace(MaximumVersion)) || (!string.IsNullOrWhiteSpace(MinimumVersion)))
                {
                    Error(Constants.Errors.VersionRangeAndRequiredVersionCannotBeSpecifiedTogether);
                }
            }

            // keep track of what package names the user asked for.
            if (!Name.IsNullOrEmpty())
            {
                foreach (var name in Name)
                {
                    _namesProcessed.GetOrAdd(name, () => false);
                }
            }

            var requests = (Name.IsNullOrEmpty() ?

                            // if the user didn't specify any names
                            SelectedProviders.Select(pv => new {
                query = "?",
                packages = pv.GetInstalledPackages("", RequiredVersion, MinimumVersion, MaximumVersion, this.ProviderSpecific(pv)).CancelWhen(CancellationEvent.Token)
            }) :

                            // if the user specified a name,
                            SelectedProviders.SelectMany(pv => {
                // for a given provider, if we get an error, we want just that provider to stop.
                var host = this.ProviderSpecific(pv);

                return(Name.Select(name => new {
                    query = name,
                    packages = pv.GetInstalledPackages(name, RequiredVersion, MinimumVersion, MaximumVersion, host).CancelWhen(CancellationEvent.Token)
                }));
            })).ToArray();

            var potentialPackagesToProcess = new System.Collections.ObjectModel.Collection <SoftwareIdentity>();

            while (WaitForActivity(requests.Select(each => each.packages)))
            {
                // keep processing while any of the the queries is still going.
                foreach (var result in requests.Where(each => each.packages.HasData))
                {
                    // look only at requests that have data waiting.

                    foreach (var package in result.packages.GetConsumingEnumerable())
                    {
                        // process the results for that set.

                        if (IsPackageInVersionRange(package))
                        {
                            // it only counts if the package is in the range we're looking for.

                            // mark down that we found something for that query
                            _namesProcessed.AddOrSet(result.query, true);

                            // If AllVersions is specified, process the package immediately
                            if (AllVersions)
                            {
                                // Process the package immediately if -AllVersions are required
                                ProcessPackage(package);
                            }
                            else
                            {
                                // Save to perform post-processing to eliminate duplicate versions and group by Name
                                potentialPackagesToProcess.Add(package);
                            }
                        }
                    }
                }
                // just work with whatever is not yet consumed
                requests = requests.FilterWithFinalizer(each => each.packages.IsConsumed, each => each.packages.Dispose()).ToArray();
            } // end of WaitForActivity()

            // Peform post-processing only if -AllVersions is not specified
            if (!AllVersions)
            {
                // post processing the potential packages as we have to display only
                // 1 package per name (note multiple versions of the same package may be installed)
                // In general, it is good practice to show only the latest one.

                // However there are cases when the same package can be found by different providers. in that case, we will show
                // the packages from different providers even through they have the same package name. This is important because uninstall-package
                // inherts from get-package, so that when the first provider does not implement the uninstall-package(), such as Programs, others will
                // perform the uninstall.

                //grouping packages by package name first
                var enumerablePotentialPackages = from p in potentialPackagesToProcess
                                                  group p by p.Name
                                                  into grouping
                                                  select grouping.OrderByDescending(pp => pp, SoftwareIdentityVersionComparer.Instance);

                //each group of packages with the same name, return the first if the packages are from the same provider
                foreach (var potentialPackage in enumerablePotentialPackages.Select(pp => (from p in pp
                                                                                           group p by p.ProviderName
                                                                                           into grouping
                                                                                           select grouping.OrderByDescending(each => each, SoftwareIdentityVersionComparer.Instance).First())).SelectMany(pkgs => pkgs.ToArray()))
                {
                    ProcessPackage(potentialPackage);
                }
            }

            return(true);
        }