/// <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; }