Beispiel #1
0
        /// <summary>
        /// The (non-static) startup method
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        /// <returns>Process return code.</returns>
        /// <remarks></remarks>
        protected override int Main(IEnumerable<string> args)
        {
            _packageManager.Elevate().Wait();

            CurrentTask.Events += new DownloadProgress((remoteLocation, location, progress) => {
                if (!activeDownloads.Contains(remoteLocation)) {
                    activeDownloads.Add(remoteLocation);
                }
                "Downloading {0}".format(remoteLocation.UrlDecode()).PrintProgressBar(progress);
            });

            CurrentTask.Events += new DownloadCompleted((remoteLocation, locallocation) => {
                if (activeDownloads.Contains(remoteLocation)) {
                    Console.WriteLine();
                    activeDownloads.Remove(remoteLocation);
                }
            });

            try {
                #region command line parsing

                var options = args.Where(each => each.StartsWith("--")).Switches();
                var parameters = args.Where(each => !each.StartsWith("--")).Parameters().ToArray();

                foreach (var arg in options.Keys) {
                    var argumentParameters = options[arg];
                    var last = argumentParameters.LastOrDefault();
                    var lastAsBool = string.IsNullOrEmpty(last) || last.IsTrue();

                    switch (arg) {
                            /* options  */
                        case "min-version":
                            pkgFilter &= Package.Properties.Version.IsGreaterThanOrEqual(last);
                            break;

                        case "max-version":
                            pkgFilter &= Package.Properties.Version.IsLessThanOrEqual(last);
                            break;

                        case "installed":
                            pkgFilter &= Package.Properties.Installed.Is(lastAsBool);
                            break;

                        case "active":
                            pkgFilter &= Package.Properties.Active.Is(lastAsBool);
                            break;

                        case "wanted":
                            pkgFilter &= Package.Properties.Wanted.Is(lastAsBool);
                            break;

                        case "blocked":
                            pkgFilter &= Package.Properties.Blocked.Is(lastAsBool);
                            break;

                        case "trimable":
                            pkgFilter &= Package.Filters.Trimable;
                            break;

                        case "latest":
                            collectionFilter = collectionFilter.Then(p=> p.HighestPackages());
                            break;

                        case "force":
                            _force = lastAsBool;
                            break;

                        case "force-scan":
                        case "force-rescan":
                        case "scan":
                        case "rescan":
                            preCommandTasks.Add(_packageManager.SetAllFeedsStale());
                            break;

                        case "pretend":
                            _pretend= lastAsBool;
                            break;

                        case "auto-upgrade":
                            _autoUpgrade = lastAsBool;
                            break;

                        case "exact":
                            _autoUpgrade = false;
                            break;

                        case "use-feed":
                        case "feed":
                            _location = last;
                            break;

                        case "verbose":
                            _verbose = lastAsBool;
                            Logger.Errors = true;
                            Logger.Messages = true;
                            Logger.Warnings = true;
                            _packageManager.EnableMessageLogging();
                            _packageManager.EnableWarningLogging();
                            _packageManager.EnableErrorLogging();
                            break;

                            /* global switches */
                        case "load-config":
                            // all ready done, but don't get too picky.
                            break;

                        case "nologo":
                            this.Assembly().SetLogo(string.Empty);
                            break;

                        case "terse":
                            this.Assembly().SetLogo(string.Empty);
                            _terse = true;
                            _verbose = false;
                            break;

                        case "x64":
                            _x64 = true;
                            break;

                        case "x86":
                            _x86 = true;
                            break;

                        case "any":
                        case "cpuany":
                            _cpuany = true;
                            break;

                        case "all":
                            _x64 = true;
                            _x86 = true;
                            _cpuany = true;
                            break;

                        case "priority":
                            switch( last ) {
                                case "highest":
                                    _priority = 100;
                                    break;
                                case "high":
                                    _priority = 75;
                                    break;
                                case "normal":
                                case "default":
                                    _priority = 50;
                                    break;
                                case "low":
                                    _priority = 25;
                                    break;
                                case "lowest":
                                    _priority = 0;
                                    break;
                                default:
                                    _priority = last.ToInt32(50);
                                    break;
                            }
                            break;

                        case "help":
                            return Help();

                        default:
                            throw new ConsoleException(Resources.UnknownParameter, arg);
                    }
                }

                Logo();

                if (!parameters.Any()) {
                    throw new ConsoleException(Resources.MissingCommand);
                }

                #endregion

                Task task = null;
                if (parameters.IsNullOrEmpty()) {
                    return Help();
                }
                string command = string.Empty;

                if (parameters[0].ToLower().EndsWith(".msi")) {
                    var files = parameters.FindFilesSmarter().ToArray();
                    if( files.Length > 0 ) {
                        // assume install if just given filenames
                        command = "install";
                        parameters = files;
                    }
                }

                if (string.IsNullOrEmpty(command)) {
                    command = parameters.FirstOrDefault();
                    parameters = parameters.Skip(1).ToArray();
                }

                if (!command.StartsWith("-")) {
                    command = command.ToLower();
                }

                switch (command) {
                    case "-?":
                        return Help();

                    case "test":
                       // pkgFilter &= Package.Properties.Installed.Is(true) & Package.Properties.Active.Is(true) & Package.Properties.UpdatePackages.Any();
                          // collectionFilter = collectionFilter.Then(p => p.HighestPackages()).Then(p => p.OrderByDescending(each=> each.Version));
                        // collectionFilter = collectionFilter.Then(p => p.HighestPackages());
                        // collectionFilter = collectionFilter.Then(pkgs => pkgs.HighestPackages());

                        pkgFilter &= Package.Properties.DisplayName.Is("z*");

                         task = preCommandTasks.Continue(() => _packageManager.FindPackages(CanonicalName.AllPackages, pkgFilter, collectionFilter, _location))
                            .Continue(packages => {
                                if (packages.IsNullOrEmpty()) {
                                    PrintNoPackagesFound(parameters);
                                    return;
                                }
                               PrintPackages(packages);
                            });

                        //_packageManager.AddScheduledTask("test", "c:\\programdata\\bin\\coapp.exe", "list", 11, 28, DayOfWeek.Tuesday, 5).Wait();
                        //var tsks = _packageManager.ScheduledTasks.Result;
                        //tsks.ToTable().ConsoleOut();

                        _packageManager.SetConfigurationValue("test", null, null).Wait();
                        Console.WriteLine( _packageManager.GetConfigurationValue("test", "something").Result);
                        return 0;

                    case "show-debug":
                        var l = 5;
                        if( parameters.Any() ) {
                            l = parameters.FirstOrDefault().ToInt32();
                        }
                        Console.WriteLine(_packageManager.GetEventLog(new TimeSpan(0, l, 0)));
                        return 0;

                    case "clear-debug":
                        Logger.Clear();
                        Console.WriteLine("Debug log cleared.");
                        return 0;

                    case "post-debug":
                        l = 5;
                        if( parameters.Any() ) {
                            l = parameters.FirstOrDefault().ToInt32();
                        }

                        var token = _packageManager.UploadDebugInformation(_packageManager.GetEventLog(new TimeSpan(0, l, 0))).Result;
                        if( string.IsNullOrEmpty(token)) {
                            return Fail("Unable to upload debug log.");
                        }

                        Console.WriteLine( "Debug Log Uploaded. Token [{0}]", token);
                        return 0;

                    case "-l":
                    case "list":
                    case "list-package":
                    case "list-packages":
                        if( !parameters.Any() ) {
                            collectionFilter = collectionFilter.Then(p => p.HighestPackages());
                        }

                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters, pkgFilter, collectionFilter, _location)
                            .Continue(packages => {
                                if (packages.IsNullOrEmpty()) {
                                    PrintNoPackagesFound(parameters);
                                    return;
                                }
                                PrintPackages(packages);
                            }));
                        break;

                    case "add-publisher":
                    case "add-publishers":
                        if( !parameters.Any()) {
                            return Fail("add-publisher requires one or more public key tokens to add");
                        }

                        task = parameters.Select(each => _packageManager.AddTrustedPublisher(each)).Continue(() => _packageManager.TrustedPublishers).Continue(publishers => {
                            Console.WriteLine("Trusted publisher key tokens: ");
                            foreach( var t in publishers ) {
                                Console.WriteLine("      {0}", t);
                            }
                        });
                        break;

                    case "remove-publisher":
                    case "remove-publishers":
                        if( !parameters.Any()) {
                            return Fail("remove-publisher requires one or more public key tokens to add");
                        }

                        task = parameters.Select(each => _packageManager.RemoveTrustedPublisher(each)).Continue(() => _packageManager.TrustedPublishers).Continue(publishers => {
                            Console.WriteLine("Trusted publisher key tokens: ");
                            foreach (var t in publishers) {
                                Console.WriteLine("      {0}", t);
                            }
                        });
                        break;

                    case "list-publishers":
                    case "list-publisher":
                        task = _packageManager.TrustedPublishers.Continue(publishers => {
                            Console.WriteLine("Trusted publisher key tokens: ");
                            foreach (var t in publishers) {
                                Console.WriteLine("      {0}", t);
                            }
                        });
                        break;

                    case "-w":
                    case "wanted":
                    case "want":
                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters, pkgFilter & Package.Filters.InstalledPackages, collectionFilter, _location)
                            .Continue(packages => {
                                if (packages.IsNullOrEmpty()) {
                                    PrintNoPackagesFound(parameters);
                                    return;
                                }
                                var pkgs = packages.ToArray();

                                Console.WriteLine("Setting {0} packages to 'wanted':", pkgs.Length);

                                foreach( var p in packages ) {
                                    _packageManager.SetPackageWanted(p.CanonicalName, true);
                                }

                                // refresh
                                pkgs.Select(each => _packageManager.GetPackage(each.CanonicalName)).Continue( p => PrintPackages(p));
                            }));
                        break;

                    case "-W":
                    case "drop":
                    case "unwanted":
                    case "unwant":
                    case "donotwant":
                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters, pkgFilter & Package.Filters.InstalledPackages, collectionFilter, _location)
                            .Continue(packages => {
                                if (packages.IsNullOrEmpty()) {
                                    PrintNoPackagesFound(parameters);
                                    return;
                                }
                                var pkgs = packages.ToArray();

                                Console.WriteLine("Setting {0} packages to 'unwanted':", pkgs.Length);

                                foreach (var p in packages) {
                                    _packageManager.SetPackageWanted(p.CanonicalName, false);
                                }

                                // refresh
                                pkgs.Select(each => _packageManager.GetPackage(each.CanonicalName)).Continue(p => PrintPackages(p));
                            }));
                        break;

                    case "block":
                    case "block-package":
                    case "-b":
                        task = preCommandTasks.Continue(() => {
                                foreach (var cn in parameters.Select(v => (CanonicalName)v)) {
                                    _packageManager.SetGeneralPackageInformation(_priority, cn, "state", PackageState.Blocked.ToString());
                                    Console.WriteLine("Blocking '{0}' at priority {1}.",cn.ToString(), _priority  );
                                }
                            });
                        break;

                    case "lock-package":
                    case "lock":
                    case "-B":
                        task = preCommandTasks.Continue(() => {
                            foreach (var cn in parameters.Select(v => (CanonicalName)v)) {
                                _packageManager.SetGeneralPackageInformation(_priority, cn, "state", PackageState.DoNotChange.ToString());
                                Console.WriteLine("Locking '{0}' at priority {1}.", cn.ToString(), _priority);
                            }
                        });
                        break;

                    case "updateable":
                    case "-d":
                        task = preCommandTasks.Continue(() => {
                            foreach (var cn in parameters.Select(v => (CanonicalName)v)) {
                                _packageManager.SetGeneralPackageInformation(_priority, cn, "state", PackageState.Updatable.ToString());
                                Console.WriteLine("Setting updatable on '{0}' at priority {1}.", cn.ToString(), _priority);
                            }
                        });
                        break;

                    case "upgradable":
                    case "-G":
                        task = preCommandTasks.Continue(() => {
                            foreach (var cn in parameters.Select(v => (CanonicalName)v)) {
                                _packageManager.SetGeneralPackageInformation(_priority, cn, "state", PackageState.Updatable.ToString());
                                Console.WriteLine("Setting upgradable on '{0}' at priority {1}.", cn.ToString(), _priority);
                            }
                        });
                        break;

                    case "-i":
                    case "install":
                    case "install-package":
                    case "install-packages":
                        if (!parameters.Any()) {
                            throw new ConsoleException(Resources.InstallRequiresPackageName);
                        }
                        task = preCommandTasks.Continue(() =>InstallPackages(parameters));
                        break;

                    case "-r":
                    case "remove":
                    case "uninstall":
                    case "remove-package":
                    case "remove-packages":
                    case "uninstall-package":
                    case "uninstall-packages":
                        if (!parameters.Any()) {
                            throw new ConsoleException(Resources.RemoveRequiresPackageName);
                        }

                        task = preCommandTasks.Continue(() =>RemovePackages(parameters));
                        break;

                    case "-L":
                    case "feed":
                    case "feeds":
                    case "list-feed":
                    case "list-feeds":
                        task = preCommandTasks.Continue((Func<Task>)ListFeeds);
                        break;

                    case "-U":
                    case "upgrade":
                    case "upgrade-package":
                    case "upgrade-packages":

                        pkgFilter = pkgFilter & Package.Filters.PackagesWithUpgradeAvailable;

                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters, pkgFilter, collectionFilter, _location)
                           .Continue(packages => {
                               if (packages.IsNullOrEmpty()) {
                                   PrintNoPackagesFound(parameters);
                                   return;
                               }

                               InstallPackages(packages.Select(each => (Package)each.AvailableNewestUpdate)).Wait();
                           }));

                        break;

                    case "-u":
                    case "update":
                    case "update-package":
                    case "update-packages":
                        pkgFilter = pkgFilter & Package.Filters.PackagesWithUpdateAvailable;

                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters, pkgFilter, collectionFilter, _location)
                           .Continue(packages => {
                               if (packages.IsNullOrEmpty()) {
                                   PrintNoPackagesFound(parameters);
                                   return;
                               }

                               InstallPackages(packages.Select(each => (Package)each.AvailableNewestUpdate)).Wait();
                           }));

                        break;

                    case "-A":
                    case "add-feed":
                    case "add-feeds":
                    case "add":
                        if (!parameters.Any()) {
                            throw new ConsoleException(Resources.AddFeedRequiresLocation);
                        }
                        task =  preCommandTasks.Continue(() => AddFeed(parameters));
                        break;

                    case "-D":
                    case "-R":
                    case "delete":
                    case "delete-feed":
                    case "delete-feeds":
                        if (!parameters.Any()) {
                            throw new ConsoleException(Resources.DeleteFeedRequiresLocation);
                        }
                        task = preCommandTasks.Continue(() => DeleteFeed(parameters));
                        break;

                    case "-t":
                    case "trim-packages":
                    case "trim-package":
                    case "trim":
                        pkgFilter &= Package.Filters.Trimable;
                        task = preCommandTasks.Continue(() =>RemovePackages(parameters));
                        break;

                    case "set-feed-active":
                    case "feed-active":
                    case "activate-feed":
                        task = preCommandTasks.Continue(() => MatchFeeds(parameters)).Continue(feeds => {
                            feeds.Select(each => _packageManager.SetFeed(each, FeedState.Active)).ToArray();
                        });

                        break;
                    case "set-feed-passive":
                    case "feed-passive":
                    case "passivate-feed":
                        task = preCommandTasks.Continue(() => MatchFeeds(parameters)).Continue(feeds => {
                            feeds.Select(each => _packageManager.SetFeed(each, FeedState.Passive)).ToArray();
                        });
                        break;
                    case "set-feed-ignored":
                    case "set-feed-ignore":
                    case "feed-ignored":
                    case "feed-ignore":
                    case "disable-feed":
                        task = preCommandTasks.Continue(() => MatchFeeds(parameters)).Continue(feeds => {
                            feeds.Select(each => _packageManager.SetFeed(each, FeedState.Ignored)).ToArray();
                        });
                        break;
            #if DEPRECATED
                    case "-a":
                    case "activate":
                    case "activate-package":
                    case "activate-packages":
                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters, pkgFilter & Package.Properties.Installed.Is(true),null, _location)
                            .Continue(packages => Activate(parameters, packages)));

                        break;
            #endif
                    case "-g":
                    case "get-packageinfo":
                    case "info":
                        task = preCommandTasks.Continue(() => _packageManager.QueryPackages(parameters,pkgFilter,null, _location)
                            .Continue(packages => GetPackageInfo(parameters,packages)));
                        break;

                    case "enable-telemetry":
                        task = preCommandTasks.Continue(() => _packageManager.SetTelemetry(true)).ContinueAlways((a)=> {
                            Console.WriteLine("Telemetry is currently set to : {0}", _packageManager.GetTelemetry().Result ? "Enabled" : "Disabled");
                        });
                        break;

                    case "telemetry":
                        task = preCommandTasks.Continue(() => {
                            Console.WriteLine("Telemetry is currently set to : {0}", _packageManager.GetTelemetry().Result ? "Enabled" : "Disabled");
                        });
                        break;

                    case "disable-telemetry":
                        task = preCommandTasks.Continue(() => _packageManager.SetTelemetry(false)).ContinueAlways((a) => {
                            Console.WriteLine("Telemetry is currently set to : {0}", _packageManager.GetTelemetry().Result ? "Enabled" : "Disabled");
                        });
                        break;

                    case "create-symlink":
                        if (parameters.Count() != 2) {
                            throw new ConsoleException("Create-symlink requires two parameters: existing-location and new-link");
                        }
                        task = preCommandTasks.Continue(() =>  _packageManager.CreateSymlink(parameters.First().GetFullPath(), parameters.Last().GetFullPath()));
                        break;

                    case "create-hardlink":
                        if (parameters.Count() != 2) {
                            throw new ConsoleException("Create-hardlink requires two parameters: existing-location and new-link");
                        }
                        task = preCommandTasks.Continue(() =>  _packageManager.CreateHardlink(parameters.First().GetFullPath(), parameters.Last().GetFullPath()));
                        break;

                    case "create-shortcut":
                        if (parameters.Count() != 2) {
                            throw new ConsoleException("Create-shortcut requires two parameters: existing-location and new-link");
                        }
                        task = preCommandTasks.Continue(() =>  _packageManager.CreateShortcut(parameters.First().GetFullPath(), parameters.Last().GetFullPath()));
                        break;

                    case "-p" :
                    case "list-policies":
                    case "list-policy":
                    case "policies":
                        task = preCommandTasks.Continue(() =>  ListPolicies() );
                        break;

                    case "add-to-policy": {
                        if (parameters.Count() != 2) {
                            throw new ConsoleException("Add-to-policy requires two parameters (policy name and account)");
                        }

                        var policyName = parameters.First();
                        var account = parameters.Last();

                        task = preCommandTasks.Continue(() => {
                            _packageManager.GetPolicy(policyName).Continue(policy => {
                                // found the policy, so continue.
                                _packageManager.AddToPolicy(policyName, account).Continue(() => {
                                    Console.WriteLine("Account '{0} added to policy '{1}", account, policyName);
                                    ListPolicies(policyName);
                                });
                            });
                        });
                    }
                        break;

                    case "remove-from-policy": {
                            if (parameters.Count() != 2) {
                                throw new ConsoleException("remove-from-policy requires two parameters (policy name and account)");
                            }

                            var policyName = parameters.First();
                            var account = parameters.Last();

                            task = preCommandTasks.Continue(() => {
                                _packageManager.GetPolicy(policyName).Continue(policy => {
                                    // found the policy, so continue.
                                    _packageManager.RemoveFromPolicy(policyName, account).Continue(() => {
                                        Console.WriteLine("Account '{0} removed from policy '{1}", account, policyName);
                                        ListPolicies(policyName);
                                    });
                                });
                            });
                        }
                        break;

                    default:
                        throw new ConsoleException(Resources.UnknownCommand, command);
                }

                task.ContinueOnCanceled(() => {
                    // the task was cancelled, and presumably dealt with.
                    Fail("Operation Canceled.");
                });

                task.ContinueOnFail((exception) => {
                    exception = exception.Unwrap();
                    if (!(exception is OperationCanceledException)) {
                        var phpue = exception as PackageHasPotentialUpgradesException;
                        if (phpue != null) {
                            // we've been told something we've asked for has a newer package available, and we didn't tell it that we either wanted it or an auto-upgrade
                            PrintPotentialUpgradeInformation(phpue.UnsatisfiedPackage, phpue.SatifactionOptions);
                            phpue.Cancel(); // marks this exception as handled.
                            return;
                        }

                        // handle coapp exceptions as cleanly as possible.
                        var ce = exception as CoAppException;
                        if (ce != null) {
                            // Fail("Alternative");
                            Fail(ce.Message);

                            ce.Cancel();
                            return;
                        }
                    }

                    // hmm. The plan did not work out so well.
                    Fail("Error (???): {0}-{1}\r\n\r\n{2}", exception.GetType(), exception.Message, exception.StackTrace);

                });

                task.Continue(() => {
                    Console.WriteLine("Done.");
                }).Wait();
            }
            catch (ConsoleException failure) {
                Fail("{0}\r\n\r\n    {1}", failure.Message, Resources.ForCommandLineHelp);
                CancellationTokenSource.Cancel();
            }
            return 0;
        }