/// <summary> /// Sets up the configuration based on arguments passed in, config file, and environment /// </summary> /// <param name="args">The arguments.</param> /// <param name="config">The configuration.</param> /// <param name="fileSystem">The file system.</param> /// <param name="xmlService">The XML service.</param> /// <param name="notifyWarnLoggingAction">Notify warn logging action</param> public static void set_up_configuration(IList<string> args, ChocolateyConfiguration config, IFileSystem fileSystem, IXmlService xmlService, Action<string> notifyWarnLoggingAction) { set_file_configuration(config, fileSystem, xmlService, notifyWarnLoggingAction); ConfigurationOptions.reset_options(); set_global_options(args, config); set_environment_options(config); }
public void handle_additional_argument_parsing(IList<string> unparsedArguments, ChocolateyConfiguration configuration) { // don't set configuration.Input or it will be passed to list if (unparsedArguments.Count > 1) { throw new ApplicationException("A single pin command must be listed. Please see the help menu for those commands"); } var command = PinCommandType.unknown; string unparsedCommand = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault(); Enum.TryParse(unparsedCommand, true, out command); if (command == PinCommandType.unknown) { if (!string.IsNullOrWhiteSpace(unparsedCommand)) this.Log().Warn("Unknown command {0}. Setting to list.".format_with(unparsedCommand)); command = PinCommandType.list; } configuration.PinCommand.Command = command; configuration.Sources = ApplicationParameters.PackagesLocation; configuration.ListCommand.LocalOnly = true; configuration.AllVersions = true; configuration.Prerelease = true; }
public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Pack Command"); this.Log().Info(@" Chocolatey will attempt to package a nuspec into a compiled nupkg. Some may prefer to use `cpack` as a shortcut for `choco pack`. NOTE: 100% compatible with older chocolatey client (0.9.8.32 and below) with options and switches. In most cases you can still pass options and switches with one dash (`-`). For more details, see the command reference (`choco -?`). NOTE: `cpack` has been deprecated as it has a name collision with CMake. Please use `choco pack` instead. The shortcut will be removed in v1. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage"); "chocolatey".Log().Info(@" choco pack [<path to nuspec>] [<options/switches>] cpack [<path to nuspec>] [<options/switches>] (DEPRECATED) "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples"); "chocolatey".Log().Info(@" choco pack choco pack --version 1.2.3 choco pack path/to/nuspec choco pack --outputdirectory build "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); }
public static IEnumerable<IPackage> GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger) { var packageRepository = NugetCommon.GetRemoteRepository(configuration, nugetLogger); IQueryable<IPackage> results = packageRepository.Search(configuration.Input, configuration.Prerelease); if (configuration.AllVersions) { return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id); } if (configuration.Prerelease && packageRepository.SupportsPrereleasePackages) { results = results.Where(p => p.IsAbsoluteLatestVersion); } else { results = results.Where(p => p.IsLatestVersion); } if (configuration.ListCommand.Page.HasValue) { results = results.Skip(configuration.ListCommand.PageSize * configuration.ListCommand.Page.Value).Take(configuration.ListCommand.PageSize); } return results.OrderBy(p => p.Id) .AsEnumerable() .Where(PackageExtensions.IsListed) .Where(p => configuration.Prerelease || p.IsReleaseVersion()) .distinct_last(PackageEqualityComparer.Id, PackageComparer.Version); }
public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Pack Command"); this.Log().Info(@" Chocolatey will attempt to package a nuspec into a compiled nupkg. Some may prefer to use `cpack` as a shortcut for `choco pack`. NOTE: `cpack` has been deprecated as it has a name collision with CMake. Please use `choco pack` instead. The shortcut will be removed in v1. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage"); "chocolatey".Log().Info(@" choco pack [<path to nuspec>] [<options/switches>] cpack [<path to nuspec>] [<options/switches>] (DEPRECATED) "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples"); "chocolatey".Log().Info(@" choco pack choco pack --version 1.2.3 choco pack path/to/nuspec "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); }
private static IQueryable<IPackage> execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger) { var packageRepository = NugetCommon.GetRemoteRepository(configuration, nugetLogger); // Whether or not the package is remote determines two things: // 1. Does the repository have a notion of "listed"? // 2. Does it support prerelease in a straight-forward way? // Choco previously dealt with this by taking the path of least resistance and manually filtering out and sort unwanted packages // This result in blocking operations that didn't let service based repositories, like OData, take care of heavy lifting on the server. bool isRemote; var aggregateRepo = packageRepository as AggregateRepository; if (aggregateRepo != null) { isRemote = aggregateRepo.Repositories.All(repo => repo is IServiceBasedRepository); } else { isRemote = packageRepository is IServiceBasedRepository; } IQueryable<IPackage> results = packageRepository.Search(configuration.Input, configuration.Prerelease); if (configuration.AllVersions) { if (isRemote) { return results.OrderBy(p => p.Id); } else { return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id).AsQueryable(); } } if (configuration.Prerelease && packageRepository.SupportsPrereleasePackages) { results = results.Where(p => p.IsAbsoluteLatestVersion); } else { results = results.Where(p => p.IsLatestVersion); } if (!isRemote) { results = results .Where(PackageExtensions.IsListed) .Where(p => configuration.Prerelease || p.IsReleaseVersion()) .distinct_last(PackageEqualityComparer.Id, PackageComparer.Version) .AsQueryable(); } if (configuration.ListCommand.Page.HasValue) { results = results.Skip(configuration.ListCommand.PageSize * configuration.ListCommand.Page.Value).Take(configuration.ListCommand.PageSize); } return results.OrderBy(p => p.Id); }
public void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "List/Search Command"); this.Log().Info(@" Chocolatey will perform a search for a package local or remote. Some may prefer to use `clist` as a shortcut for `choco list`. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage"); "chocolatey".Log().Info(@" choco search <filter> [<options/switches>] choco list <filter> [<options/switches>] clist <filter> [<options/switches>] "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples"); "chocolatey".Log().Info(@" choco list --local-only choco list -li choco list -lai choco search git choco search git -s ""https://somewhere/out/there"" choco search bob -s ""https://somewhere/protected"" -u user -p pass "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); }
public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", "Source - The source to find the package(s) to install. Special sources include: ruby, webpi, cygwin, windowsfeatures, and python. Defaults to default feeds.", option => configuration.Sources = option) .Add("version=", "Version - A specific version to uninstall. Defaults to unspecified.", option => configuration.Version = option.remove_surrounding_quotes()) .Add("a|allversions|all-versions", "AllVersions - Uninstall all versions? Defaults to false.", option => configuration.AllVersions = option != null) .Add("ua=|uninstallargs=|uninstallarguments=|uninstall-arguments=", "UninstallArguments - Uninstall Arguments to pass to the native installer in the package. Defaults to unspecified.", option => configuration.InstallArguments = option.remove_surrounding_quotes()) .Add("o|override|overrideargs|overridearguments|override-arguments", "OverrideArguments - Should uninstall arguments be used exclusively without appending to current package passed arguments? Defaults to false.", option => configuration.OverrideArguments = option != null) .Add("notsilent|not-silent", "NotSilent - Do not uninstall this silently. Defaults to false.", option => configuration.NotSilent = option != null) .Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=", "PackageParameters - Parameters to pass to the package. Defaults to unspecified.", option => configuration.PackageParameters = option.remove_surrounding_quotes()) .Add("x|forcedependencies|force-dependencies|removedependencies|remove-dependencies", "RemoveDependencies - Uninstall dependencies when uninstalling package(s). Defaults to false.", option => configuration.ForceDependencies = option != null) .Add("n|skippowershell|skip-powershell", "Skip Powershell - Do not run chocolateyUninstall.ps1. Defaults to false.", option => configuration.SkipPackageInstallProvider = option != null) ; }
public override void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add( "s=|source=", "Source - Source location for install. Can include special 'webpi'. Defaults to sources.", option => configuration.Sources = option.remove_surrounding_quotes()) .Add( "l|lo|localonly|local-only", "LocalOnly - Only search against local machine items.", option => configuration.ListCommand.LocalOnly = option != null) .Add( "pre|prerelease", "Prerelease - Include Prereleases? Defaults to false.", option => configuration.Prerelease = option != null) .Add( "u=|user="******"User - used with authenticated feeds. Defaults to empty.", option => configuration.SourceCommand.Username = option.remove_surrounding_quotes()) .Add( "p=|password="******"Password - the user's password to the source. Defaults to empty.", option => configuration.SourceCommand.Password = option.remove_surrounding_quotes()) ; }
public void handle_validation(ChocolateyConfiguration configuration) { if (configuration.FeatureCommand.Command != FeatureCommandType.list && string.IsNullOrWhiteSpace(configuration.FeatureCommand.Name)) { throw new ApplicationException("When specifying the subcommand '{0}', you must also specify --name.".format_with(configuration.FeatureCommand.Command.to_string())); } }
public void feature_enable(ChocolateyConfiguration configuration) { var feature = configFileSettings.Features.FirstOrDefault(p => p.Name.is_equal_to(configuration.FeatureCommand.Name)); if (feature == null) { throw new ApplicationException("Feature '{0}' not found".format_with(configuration.FeatureCommand.Name)); } if (!feature.Enabled || !feature.SetExplicitly) { if (feature.Enabled && !feature.SetExplicitly) { this.Log().Info(() => "{0} was enabled by default. Explicitly setting value.".format_with(feature.Name)); } feature.Enabled = true; feature.SetExplicitly = true; _xmlService.serialize(configFileSettings, ApplicationParameters.GlobalConfigFileLocation); this.Log().Warn(() => "Enabled {0}".format_with(feature.Name)); } else { this.Log().Warn(NO_CHANGE_MESSAGE); } }
public void handle_additional_argument_parsing(IList<string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); var command = ConfigCommandType.unknown; string unparsedCommand = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault().to_string().Replace("-",string.Empty); Enum.TryParse(unparsedCommand, true, out command); if (command == ConfigCommandType.unknown) { if (!string.IsNullOrWhiteSpace(unparsedCommand)) this.Log().Warn("Unknown command {0}. Setting to list.".format_with(unparsedCommand)); command = ConfigCommandType.list; } configuration.ConfigCommand.Command = command; if ((configuration.ConfigCommand.Command == ConfigCommandType.list || !string.IsNullOrWhiteSpace(configuration.ConfigCommand.Name) ) && unparsedArguments.Count > 1) throw new ApplicationException("A single features command must be listed. Please see the help menu for those commands"); if (string.IsNullOrWhiteSpace(configuration.ConfigCommand.Name) && unparsedArguments.Count >=2) { configuration.ConfigCommand.Name = unparsedArguments[1]; } if (string.IsNullOrWhiteSpace(configuration.ConfigCommand.ConfigValue) && unparsedArguments.Count >= 3) { configuration.ConfigCommand.ConfigValue = unparsedArguments[2]; } }
public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("a|auto|automaticpackage", "AutomaticPackage - Generate automatic package instead of normal. Defaults to false", option => configuration.NewCommand.AutomaticPackage = option != null) .Add("t=|template=|template-name=", "TemplateName - Use a named template in {0}\\templates\\templatename instead of built-in template.".format_with(ApplicationParameters.InstallLocation), option => configuration.NewCommand.TemplateName = option) .Add("name=", "Name [Required]- the name of the package. Can be passed as first parameter without \"--name=\".", option => { configuration.NewCommand.Name = option.remove_surrounding_quotes(); configuration.NewCommand.TemplateProperties.Add(TemplateValues.NamePropertyName, option.remove_surrounding_quotes()); }) .Add("version=", "Version - the version of the package. Can also be passed as the property PackageVersion=somevalue", option => configuration.NewCommand.TemplateProperties.Add(TemplateValues.VersionPropertyName, option.remove_surrounding_quotes())) .Add("maintainer=", "Maintainer - the name of the maintainer. Can also be passed as the property MaintainerName=somevalue", option => configuration.NewCommand.TemplateProperties.Add(TemplateValues.MaintainerPropertyName, option.remove_surrounding_quotes())) ; //todo: more built-in templates }
private static void add_or_remove_licensed_source(ChocolateyLicense license, Container container) { var addOrUpdate = license.IsValid; var config = new ChocolateyConfiguration { RegularOutput = false, QuietOutput = true, }; var sourceService = container.GetInstance<IChocolateyConfigSettingsService>(); var sources = sourceService.source_list(config); config.SourceCommand.Name = ApplicationParameters.ChocolateyLicensedFeedSourceName; config.Sources = ApplicationParameters.ChocolateyLicensedFeedSource; config.SourceCommand.Username = "******"; config.SourceCommand.Password = license.Id; config.SourceCommand.Priority = 10; if (addOrUpdate && !sources.Any(s => s.Id.is_equal_to(ApplicationParameters.ChocolateyLicensedFeedSourceName) && s.Authenticated) ) { sourceService.source_add(config); } if (!addOrUpdate) { sourceService.source_remove(config); } }
public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", "Source - Source location for install. Can include special 'webpi'. Defaults to sources.", option => configuration.Sources = option.remove_surrounding_quotes()) .Add("l|lo|localonly|local-only", "LocalOnly - Only search against local machine items.", option => configuration.ListCommand.LocalOnly = option != null) .Add("pre|prerelease", "Prerelease - Include Prereleases? Defaults to false.", option => configuration.Prerelease = option != null) .Add("i|includeprograms|include-programs", "IncludePrograms - Used in conjunction with LocalOnly, filters out apps chocolatey has listed as packages and includes those in the list. Defaults to false.", option => configuration.ListCommand.IncludeRegistryPrograms = option != null) .Add("a|all|allversions|all-versions", "AllVersions - include results from all versions.", option => configuration.AllVersions = option != null) .Add("u=|user="******"User - used with authenticated feeds. Defaults to empty.", option => configuration.SourceCommand.Username = option.remove_surrounding_quotes()) .Add("p=|password="******"Password - the user's password to the source. Defaults to empty.", option => configuration.SourceCommand.Password = option.remove_surrounding_quotes()) ; //todo exact name }
public void handle_validation(ChocolateyConfiguration configuration) { if (string.IsNullOrWhiteSpace(configuration.PackageNames)) { throw new ApplicationException("Package name is required. Please pass at least one package name to uninstall."); } }
public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = null; configuration.PushCommand.TimeoutInSeconds = 300; optionSet .Add("s=|source=", "Source - The source we are pushing the package to. Use {0} to push to community feed.".format_with(ApplicationParameters.ChocolateyCommunityFeedPushSource), option => configuration.Sources = option.remove_surrounding_quotes()) .Add("k=|key=|apikey=|api-key=", "ApiKey - The api key for the source. If not specified (and not local file source), does a lookup. If not specified and one is not found for an https source, push will fail.", option => configuration.PushCommand.Key = option.remove_surrounding_quotes()) .Add("t=|timeout=", "Timeout (in seconds) - The time to allow a package push to occur before timing out. Defaults to 300 seconds (5 minutes).", option => { int timeout = 0; int.TryParse(option, out timeout); if (timeout > 0) { configuration.PushCommand.TimeoutInSeconds = timeout; } }) //.Add("b|disablebuffering|disable-buffering", // "DisableBuffering - Disable buffering when pushing to an HTTP(S) server to decrease memory usage. Note that when this option is enabled, integrated windows authentication might not work.", // option => configuration.PushCommand.DisableBuffering = option) ; //todo: push command - allow disable buffering? }
public PoshHost(ChocolateyConfiguration configuration) { ExitCode = -1; _configuration = configuration; _psUI = new PoshHostUserInterface(configuration); _version = get_current_version(); }
public void handle_validation(ChocolateyConfiguration configuration) { if (!string.IsNullOrWhiteSpace(configuration.ApiKeyCommand.Key) && string.IsNullOrWhiteSpace(configuration.Sources)) { throw new ApplicationException("You must specify both 'source' and 'key' to set an api key."); } }
public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("a|auto|automaticpackage", "AutomaticPackage - Generate automatic package instead of normal. Defaults to false", option => configuration.NewCommand.AutomaticPackage = option != null) .Add("t=|template=|template-name=", "TemplateName - Use a named template in {0}\\templates\\templatename instead of built-in template. Available in 0.9.9.9+. Manage templates as packages in 0.9.10+.".format_with(ApplicationParameters.InstallLocation), option => configuration.NewCommand.TemplateName = option) .Add("name=", "Name [Required]- the name of the package. Can be passed as first parameter without \"--name=\".", option => { configuration.NewCommand.Name = option.remove_surrounding_quotes(); configuration.NewCommand.TemplateProperties.Add(TemplateValues.NamePropertyName, option.remove_surrounding_quotes()); }) .Add("version=", "Version - the version of the package. Can also be passed as the property PackageVersion=somevalue", option => configuration.NewCommand.TemplateProperties.Add(TemplateValues.VersionPropertyName, option.remove_surrounding_quotes())) .Add("maintainer=", "Maintainer - the name of the maintainer. Can also be passed as the property MaintainerName=somevalue", option => configuration.NewCommand.TemplateProperties.Add(TemplateValues.MaintainerPropertyName, option.remove_surrounding_quotes())) .Add("outputdirectory=", "OutputDirectory - Specifies the directory for the created Chocolatey package file. If not specified, uses the current directory. Available in 0.9.10+.", option => configuration.OutputDirectory = option) .Add("built-in|built-in-template|originaltemplate|original-template|use-original-template|use-built-in-template", "BuiltInTemplate - Use the original built-in template instead of any override. Available in 0.9.10+.", option => configuration.NewCommand.UseOriginalTemplate = option != null) ; //todo: more built-in templates }
public void ensure_source_app_installed(ChocolateyConfiguration config, Action<PackageResult> ensureAction) { var runnerConfig = new ChocolateyConfiguration { PackageNames = WEB_PI_PACKAGE, Sources = ApplicationParameters.PackagesLocation, Debug = config.Debug, Force = config.Force, Verbose = config.Verbose, CommandExecutionTimeoutSeconds = config.CommandExecutionTimeoutSeconds, CacheLocation = config.CacheLocation, RegularOutput = config.RegularOutput, PromptForConfirmation = false, AcceptLicense = true, }; runnerConfig.ListCommand.LocalOnly = true; var localPackages = _nugetService.list_run(runnerConfig, logResults: false); if (!localPackages.ContainsKey(WEB_PI_PACKAGE)) { runnerConfig.Sources = ApplicationParameters.ChocolateyCommunityFeedSource; var prompt = config.PromptForConfirmation; config.PromptForConfirmation = false; _nugetService.install_run(runnerConfig, ensureAction.Invoke); config.PromptForConfirmation = prompt; } }
public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Outdated Command"); this.Log().Info(@" Returns a list of outdated packages. NOTE: Available with 0.9.9.6+. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage"); "chocolatey".Log().Info(@" choco outdated [<options/switches>] "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples"); "chocolatey".Log().Info(@" choco outdated choco outdated -s https://somewhere/out/there choco outdated -s ""'https://somewhere/protected'"" -u user -p pass If you use `--source=https://somewhere/out/there`, it is going to look for outdated packages only based on that source. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "See It In Action"); "chocolatey".Log().Info(@" choco outdated: https://raw.githubusercontent.com/wiki/chocolatey/choco/images/gifs/choco_outdated.gif "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); }
public void handle_additional_argument_parsing(IList<string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); if (string.IsNullOrWhiteSpace(configuration.NewCommand.Name)) { configuration.NewCommand.Name = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault(); var property = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault().Split(new[] {'='}, StringSplitOptions.RemoveEmptyEntries); if (property.Count() == 1) { configuration.NewCommand.TemplateProperties.Add(TemplateValues.NamePropertyName, configuration.NewCommand.Name); } } foreach (var unparsedArgument in unparsedArguments.or_empty_list_if_null()) { var property = unparsedArgument.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries); if (property.Count() == 2) { var propName = property[0].trim_safe(); var propValue = property[1].trim_safe().remove_surrounding_quotes(); if (configuration.NewCommand.TemplateProperties.ContainsKey(propName)) { this.Log().Warn(() => "A value for '{0}' has already been added with the value '{1}'. Ignoring {0}='{2}'.".format_with(propName, configuration.NewCommand.TemplateProperties[propName], propValue)); } else { configuration.NewCommand.TemplateProperties.Add(propName, propValue); } } } }
public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", "Source - The source to find the package(s) to install. Special sources include: ruby, webpi, cygwin, windowsfeatures, and python. Defaults to default feeds.", option => configuration.Sources = option.remove_surrounding_quotes()) .Add("version=", "Version - A specific version to install. Defaults to unspecified.", option => configuration.Version = option.remove_surrounding_quotes()) .Add("pre|prerelease", "Prerelease - Include Prereleases? Defaults to false.", option => configuration.Prerelease = option != null) .Add("x86|forcex86", "ForceX86 - Force x86 (32bit) installation on 64 bit systems. Defaults to false.", option => configuration.ForceX86 = option != null) .Add("ia=|installargs=|installarguments=|install-arguments=", "InstallArguments - Install Arguments to pass to the native installer in the package. Defaults to unspecified.", option => configuration.InstallArguments = option.remove_surrounding_quotes()) .Add("o|override|overrideargs|overridearguments|override-arguments", "OverrideArguments - Should install arguments be used exclusively without appending to current package passed arguments? Defaults to false.", option => configuration.OverrideArguments = option != null) .Add("notsilent|not-silent", "NotSilent - Do not install this silently. Defaults to false.", option => configuration.NotSilent = option != null) .Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=", "PackageParameters - Parameters to pass to the package. Defaults to unspecified.", option => configuration.PackageParameters = option.remove_surrounding_quotes()) .Add("allowdowngrade|allow-downgrade", "AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.", option => configuration.AllowDowngrade = option != null) .Add("m|sxs|sidebyside|side-by-side|allowmultiple|allow-multiple|allowmultipleversions|allow-multiple-versions", "AllowMultipleVersions - Should multiple versions of a package be installed? Defaults to false.", option => configuration.AllowMultipleVersions = option != null) .Add("i|ignoredependencies|ignore-dependencies", "IgnoreDependencies - Ignore dependencies when upgrading package(s). Defaults to false.", option => configuration.IgnoreDependencies = option != null) .Add("n|skippowershell|skip-powershell", "Skip Powershell - Do not run chocolateyInstall.ps1. Defaults to false.", option => configuration.SkipPackageInstallProvider = option != null) .Add("failonunfound|fail-on-unfound", "Fail On Unfound Packages - If a package is not found in feeds specified, fail instead of warn.", option => configuration.UpgradeCommand.FailOnUnfound = option != null) .Add("failonnotinstalled|fail-on-not-installed", "Fail On Non-installed Packages - If a package is not already intalled, fail instead of installing.", option => configuration.UpgradeCommand.FailOnNotInstalled = option != null) .Add("u=|user="******"User - used with authenticated feeds. Defaults to empty.", option => configuration.SourceCommand.Username = option.remove_surrounding_quotes()) .Add("p=|password="******"Password - the user's password to the source. Defaults to empty.", option => configuration.SourceCommand.Password = option.remove_surrounding_quotes()) .Add("ignorechecksums|ignore-checksums", "IgnoreChecksums - Ignore checksums provided by the package", option => { if (option != null) configuration.Features.CheckSumFiles = false; }) ; }
public void list_noop(ChocolateyConfiguration config) { this.Log().Info("{0} would have searched for '{1}' against the following source(s) :\"{2}\"".format_with( ApplicationParameters.Name, config.Input, config.Sources )); }
public PackageFiles capture_package_files(PackageResult packageResult, ChocolateyConfiguration config) { if (packageResult == null) return new PackageFiles(); var installDirectory = get_package_install_directory(packageResult); if (installDirectory == null) return null; return capture_package_files(installDirectory, config); }
public void ensure_compatible_file_attributes(PackageResult packageResult, ChocolateyConfiguration config) { if (packageResult == null) return; var installDirectory = get_package_install_directory(packageResult); if (installDirectory == null) return; ensure_compatible_file_attributes(installDirectory, config); }
public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("version=", "Version - The version you would like to insert into the package.", option => configuration.Version = option.remove_surrounding_quotes()) ; }
public override void handle_validation(ChocolateyConfiguration configuration) { this.Log().Warn(ChocolateyLoggers.Important, @" DEPRECATION NOTICE - choco update is deprecated and will be removed or replaced in version 1.0.0 with something that performs the functions of updating package indexes. Please use `choco upgrade` instead."); base.handle_validation(configuration); }
public override void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Info Command"); this.Log().Info(@" Chocolatey will perform a search for a package local or remote and provide detailed information about that package. This is a synonym for `choco search <pkgname> --exact --detailed`. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); }
public void handle_additional_argument_parsing(IList <string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); if (configuration.ListCommand.LocalOnly) { configuration.Sources = ApplicationParameters.PackagesLocation; } }
public void noop(ChocolateyConfiguration configuration) { _packageService.list_noop(configuration); }
public void handle_validation(ChocolateyConfiguration configuration) { }
public bool uninstall(ChocolateyConfiguration configuration, PackageResult packageResult) { return(run_action(configuration, packageResult, CommandNameType.uninstall)); }
public virtual void run(ChocolateyConfiguration configuration) { _packageService.ensure_source_app_installed(configuration); _packageService.install_run(configuration); }
public ConcurrentDictionary <string, PackageResult> install_run(ChocolateyConfiguration config, Action <PackageResult> continueAction) { var packageResults = new ConcurrentDictionary <string, PackageResult>(StringComparer.InvariantCultureIgnoreCase); var args = ExternalCommandArgsBuilder.build_arguments(config, _installArguments); foreach (var packageToInstall in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries)) { var argsForPackage = args.Replace(PACKAGE_NAME_TOKEN, packageToInstall); var exitCode = _commandExecutor.execute( EXE_PATH, argsForPackage, config.CommandExecutionTimeoutSeconds, ApplicationParameters.ShimsLocation, (s, e) => { var logMessage = e.Data; if (string.IsNullOrWhiteSpace(logMessage)) { return; } this.Log().Info(() => " [{0}] {1}".format_with(APP_NAME, logMessage.escape_curly_braces())); var packageName = get_value_from_output(logMessage, PackageNameRegex, PACKAGE_NAME_GROUP); var results = packageResults.GetOrAdd(packageName, new PackageResult(packageName, null, null)); if (AlreadyInstalledRegex.IsMatch(logMessage)) { results.Messages.Add(new ResultMessage(ResultType.Inconclusive, packageName)); this.Log().Warn(ChocolateyLoggers.Important, " [{0}] {1} already installed or doesn't exist. --force has no effect.".format_with(APP_NAME, string.IsNullOrWhiteSpace(packageName) ? packageToInstall : packageName)); return; } if (InstallingRegex.IsMatch(logMessage)) { this.Log().Info(ChocolateyLoggers.Important, "{0}".format_with(packageName)); return; } if (InstalledRegex.IsMatch(logMessage)) { this.Log().Info(ChocolateyLoggers.Important, " {0} has been installed successfully.".format_with(string.IsNullOrWhiteSpace(packageName) ? packageToInstall : packageName)); } }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Error(() => "[{0}] {1}".format_with(APP_NAME, e.Data.escape_curly_braces())); }, updateProcessPath: false, allowUseWindow: true ); if (exitCode != 0) { Environment.ExitCode = exitCode; } } return(packageResults); }
public virtual IEnumerable <ChocolateySource> list(ChocolateyConfiguration configuration) { return(_configSettingsService.source_list(configuration)); }
public virtual void handle_additional_argument_parsing(IList <string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); configuration.PackageNames = string.Join(ApplicationParameters.PackageNamesSeparator.to_string(), unparsedArguments.Where(arg => !arg.StartsWith("-"))); }
public void generate(ChocolateyConfiguration configuration) { var logger = ChocolateyLoggers.Normal; if (configuration.QuietOutput) { logger = ChocolateyLoggers.LogFileOnly; } var packageLocation = _fileSystem.combine_paths(configuration.OutputDirectory ?? _fileSystem.get_current_directory(), configuration.NewCommand.Name); if (_fileSystem.directory_exists(packageLocation) && !configuration.Force) { throw new ApplicationException( "The location for the template already exists. You can:{0} 1. Remove '{1}'{0} 2. Use --force{0} 3. Specify a different name".format_with(Environment.NewLine, packageLocation)); } if (configuration.RegularOutput) { this.Log().Info(logger, () => "Creating a new package specification at {0}".format_with(packageLocation)); } try { _fileSystem.delete_directory_if_exists(packageLocation, recursive: true); } catch (Exception ex) { if (configuration.RegularOutput) { this.Log().Warn(() => "{0}".format_with(ex.Message)); } } _fileSystem.create_directory_if_not_exists(packageLocation); var packageToolsLocation = _fileSystem.combine_paths(packageLocation, "tools"); _fileSystem.create_directory_if_not_exists(packageToolsLocation); var tokens = new TemplateValues(); if (configuration.NewCommand.AutomaticPackage) { tokens.set_auto(); } // now override those values foreach (var property in configuration.NewCommand.TemplateProperties) { try { tokens.GetType().GetProperty(property.Key, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase).SetValue(tokens, property.Value, null); this.Log().Debug(() => "Set token for '{0}' to '{1}'".format_with(property.Key, property.Value)); } catch (Exception) { if (configuration.RegularOutput) { this.Log().Debug("Property {0} will be added to additional properties.".format_with(property.Key)); } tokens.AdditionalProperties.Add(property.Key, property.Value); } } this.Log().Debug(() => "Token Values after merge:"); foreach (var propertyInfo in tokens.GetType().GetProperties()) { this.Log().Debug(() => " {0}={1}".format_with(propertyInfo.Name, propertyInfo.GetValue(tokens, null))); } foreach (var additionalProperty in tokens.AdditionalProperties.or_empty_list_if_null()) { this.Log().Debug(() => " {0}={1}".format_with(additionalProperty.Key, additionalProperty.Value)); } var defaultTemplateOverride = _fileSystem.combine_paths(ApplicationParameters.TemplatesLocation, "default"); if (string.IsNullOrWhiteSpace(configuration.NewCommand.TemplateName) && (!_fileSystem.directory_exists(defaultTemplateOverride) || configuration.NewCommand.UseOriginalTemplate)) { generate_file_from_template(configuration, tokens, NuspecTemplate.Template, _fileSystem.combine_paths(packageLocation, "{0}.nuspec".format_with(tokens.PackageNameLower)), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyInstallTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "chocolateyinstall.ps1"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyBeforeModifyTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "chocolateybeforemodify.ps1"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyUninstallTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "chocolateyuninstall.ps1"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyLicenseFileTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "LICENSE.txt"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyVerificationFileTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "VERIFICATION.txt"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyReadMeTemplate.Template, _fileSystem.combine_paths(packageLocation, "ReadMe.md"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyTodoTemplate.Template, _fileSystem.combine_paths(packageLocation, "_TODO.txt"), Encoding.UTF8); } else { configuration.NewCommand.TemplateName = string.IsNullOrWhiteSpace(configuration.NewCommand.TemplateName) ? "default" : configuration.NewCommand.TemplateName; var templatePath = _fileSystem.combine_paths(ApplicationParameters.TemplatesLocation, configuration.NewCommand.TemplateName); if (!_fileSystem.directory_exists(templatePath)) { throw new ApplicationException("Unable to find path to requested template '{0}'. Path should be '{1}'".format_with(configuration.NewCommand.TemplateName, templatePath)); } this.Log().Info(configuration.QuietOutput ? logger : ChocolateyLoggers.Important, "Generating package from custom template at '{0}'.".format_with(templatePath)); foreach (var file in _fileSystem.get_files(templatePath, "*.*", SearchOption.AllDirectories)) { var packageFileLocation = file.Replace(templatePath, packageLocation); var fileExtension = _fileSystem.get_file_extension(packageFileLocation); if (fileExtension.is_equal_to(".nuspec")) { packageFileLocation = _fileSystem.combine_paths(packageLocation, "{0}.nuspec".format_with(tokens.PackageNameLower)); } if (_templateBinaryExtensions.Contains(fileExtension)) { this.Log().Debug(" Treating template file ('{0}') as binary instead of replacing templated values.".format_with(_fileSystem.get_file_name(file))); _fileSystem.copy_file(file, packageFileLocation, overwriteExisting: true); } else { generate_file_from_template(configuration, tokens, _fileSystem.read_file(file), packageFileLocation, Encoding.UTF8); } } } this.Log().Info(configuration.QuietOutput ? logger : ChocolateyLoggers.Important, "Successfully generated {0}{1} package specification files{2} at '{3}'".format_with( configuration.NewCommand.Name, configuration.NewCommand.AutomaticPackage ? " (automatic)" : string.Empty, Environment.NewLine, packageLocation)); }
public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", "Source - The source to find the package(s) to install. Special sources include: ruby, webpi, cygwin, windowsfeatures, and python. To specify more than one source, pass it with a semi-colon separating the values (e.g. \"'source1;source2'\"). Defaults to default feeds.", option => configuration.Sources = option.remove_surrounding_quotes()) .Add("version=", "Version - A specific version to install. Defaults to unspecified.", option => configuration.Version = option.remove_surrounding_quotes()) .Add("pre|prerelease", "Prerelease - Include Prereleases? Defaults to false.", option => configuration.Prerelease = option != null) .Add("x86|forcex86", "ForceX86 - Force x86 (32bit) installation on 64 bit systems. Defaults to false.", option => configuration.ForceX86 = option != null) .Add("ia=|installargs=|install-args=|installarguments=|install-arguments=", "InstallArguments - Install Arguments to pass to the native installer in the package. Defaults to unspecified.", option => configuration.InstallArguments = option.remove_surrounding_quotes()) .Add("o|override|overrideargs|overridearguments|override-arguments", "OverrideArguments - Should install arguments be used exclusively without appending to current package passed arguments? Defaults to false.", option => configuration.OverrideArguments = option != null) .Add("notsilent|not-silent", "NotSilent - Do not install this silently. Defaults to false.", option => configuration.NotSilent = option != null) .Add("params=|parameters=|pkgparameters=|packageparameters=|package-parameters=", "PackageParameters - Parameters to pass to the package. Defaults to unspecified.", option => configuration.PackageParameters = option.remove_surrounding_quotes()) .Add("argsglobal|args-global|installargsglobal|install-args-global|applyargstodependencies|apply-args-to-dependencies|apply-install-arguments-to-dependencies", "Apply Install Arguments To Dependencies - Should install arguments be applied to dependent packages? Defaults to false.", option => configuration.ApplyInstallArgumentsToDependencies = option != null) .Add("paramsglobal|params-global|packageparametersglobal|package-parameters-global|applyparamstodependencies|apply-params-to-dependencies|apply-package-parameters-to-dependencies", "Apply Package Parameters To Dependencies - Should package parameters be applied to dependent packages? Defaults to false.", option => configuration.ApplyPackageParametersToDependencies = option != null) .Add("allowdowngrade|allow-downgrade", "AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.", option => configuration.AllowDowngrade = option != null) .Add("m|sxs|sidebyside|side-by-side|allowmultiple|allow-multiple|allowmultipleversions|allow-multiple-versions", "AllowMultipleVersions - Should multiple versions of a package be installed? Defaults to false.", option => configuration.AllowMultipleVersions = option != null) .Add("i|ignoredependencies|ignore-dependencies", "IgnoreDependencies - Ignore dependencies when installing package(s). Defaults to false.", option => configuration.IgnoreDependencies = option != null) .Add("x|forcedependencies|force-dependencies", "ForceDependencies - Force dependencies to be reinstalled when force installing package(s). Must be used in conjunction with --force. Defaults to false.", option => configuration.ForceDependencies = option != null) .Add("n|skippowershell|skip-powershell|skipscripts|skip-scripts|skip-automation-scripts", "Skip Powershell - Do not run chocolateyInstall.ps1. Defaults to false.", option => configuration.SkipPackageInstallProvider = option != null) .Add("u=|user="******"User - used with authenticated feeds. Defaults to empty.", option => configuration.SourceCommand.Username = option.remove_surrounding_quotes()) .Add("p=|password="******"Password - the user's password to the source. Defaults to empty.", option => configuration.SourceCommand.Password = option.remove_surrounding_quotes()) .Add("cert=", "Client certificate - PFX pathname for an x509 authenticated feeds. Defaults to empty. Available in 0.9.10+.", option => configuration.SourceCommand.Certificate = option.remove_surrounding_quotes()) .Add("cp=|certpassword="******"Certificate Password - the client certificate's password to the source. Defaults to empty. Available in 0.9.10+.", option => configuration.SourceCommand.CertificatePassword = option.remove_surrounding_quotes()) .Add("ignorechecksum|ignore-checksum|ignorechecksums|ignore-checksums", "IgnoreChecksums - Ignore checksums provided by the package. Overrides the default feature '{0}' set to '{1}'. Available in 0.9.9.9+.".format_with(ApplicationParameters.Features.ChecksumFiles, configuration.Features.ChecksumFiles.to_string()), option => { if (option != null) { configuration.Features.ChecksumFiles = false; } }) .Add("allowemptychecksum|allowemptychecksums|allow-empty-checksums", "Allow Empty Checksums - Allow packages to have empty/missing checksums for downloaded resources from non-secure locations (HTTP, FTP). Use this switch is not recommended if using sources that download resources from the internet. Overrides the default feature '{0}' set to '{1}'. Available in 0.10.0+.".format_with(ApplicationParameters.Features.AllowEmptyChecksums, configuration.Features.AllowEmptyChecksums.to_string()), option => { if (option != null) { configuration.Features.AllowEmptyChecksums = true; } }) .Add("allowemptychecksumsecure|allowemptychecksumssecure|allow-empty-checksums-secure", "Allow Empty Checksums Secure - Allow packages to have empty checksums for downloaded resources from secure locations (HTTPS). Overrides the default feature '{0}' set to '{1}'. Available in 0.10.0+.".format_with(ApplicationParameters.Features.AllowEmptyChecksumsSecure, configuration.Features.AllowEmptyChecksumsSecure.to_string()), option => { if (option != null) { configuration.Features.AllowEmptyChecksumsSecure = true; } }) .Add("requirechecksum|requirechecksums|require-checksums", "Require Checksums - Requires packages to have checksums for downloaded resources (both non-secure and secure). Overrides the default feature '{0}' set to '{1}' and '{2}' set to '{3}'. Available in 0.10.0+.".format_with(ApplicationParameters.Features.AllowEmptyChecksums, configuration.Features.AllowEmptyChecksums.to_string(), ApplicationParameters.Features.AllowEmptyChecksumsSecure, configuration.Features.AllowEmptyChecksumsSecure.to_string()), option => { if (option != null) { configuration.Features.AllowEmptyChecksums = false; configuration.Features.AllowEmptyChecksumsSecure = false; } }) .Add("checksum=|downloadchecksum=|download-checksum=", "Download Checksum - a user provided checksum for downloaded resources for the package. Overrides the package checksum (if it has one). Defaults to empty. Available in 0.10.0+.", option => configuration.DownloadChecksum = option.remove_surrounding_quotes()) .Add("checksum64=|checksumx64=|downloadchecksumx64=|download-checksum-x64=", "Download Checksum 64bit - a user provided checksum for 64bit downloaded resources for the package. Overrides the package 64-bit checksum (if it has one). Defaults to same as Download Checksum. Available in 0.10.0+.", option => configuration.DownloadChecksum64 = option.remove_surrounding_quotes()) .Add("checksumtype=|checksum-type=|downloadchecksumtype=|download-checksum-type=", "Download Checksum Type - a user provided checksum type. Overrides the package checksum type (if it has one). Used in conjunction with Download Checksum. Available values are 'md5', 'sha1', 'sha256' or 'sha512'. Defaults to 'md5'. Available in 0.10.0+.", option => configuration.DownloadChecksumType = option.remove_surrounding_quotes()) .Add("checksumtype64=|checksumtypex64=|checksum-type-x64=|downloadchecksumtypex64=|download-checksum-type-x64=", "Download Checksum Type 64bit - a user provided checksum for 64bit downloaded resources for the package. Overrides the package 64-bit checksum (if it has one). Used in conjunction with Download Checksum 64bit. Available values are 'md5', 'sha1', 'sha256' or 'sha512'. Defaults to same as Download Checksum Type. Available in 0.10.0+.", option => configuration.DownloadChecksumType64 = option.remove_surrounding_quotes()) .Add("ignorepackagecodes|ignorepackageexitcodes|ignore-package-codes|ignore-package-exit-codes", "IgnorePackageExitCodes - Exit with a 0 for success and 1 for non-success, no matter what package scripts provide for exit codes. Overrides the default feature '{0}' set to '{1}'. Available in 0.9.10+.".format_with(ApplicationParameters.Features.UsePackageExitCodes, configuration.Features.UsePackageExitCodes.to_string()), option => { if (option != null) { configuration.Features.UsePackageExitCodes = false; } }) .Add("usepackagecodes|usepackageexitcodes|use-package-codes|use-package-exit-codes", "UsePackageExitCodes - Package scripts can provide exit codes. Use those for choco's exit code when non-zero (this value can come from a dependency package). Chocolatey defines valid exit codes as 0, 1605, 1614, 1641, 3010. Overrides the default feature '{0}' set to '{1}'. Available in 0.9.10+.".format_with(ApplicationParameters.Features.UsePackageExitCodes, configuration.Features.UsePackageExitCodes.to_string()), option => configuration.Features.UsePackageExitCodes = option != null ) .Add("stoponfirstfailure|stop-on-first-failure|stop-on-first-package-failure", "Stop On First Package Failure - stop running install, upgrade or uninstall on first package failure instead of continuing with others. Overrides the default feature '{0}' set to '{1}'. Available in 0.10.4+.".format_with(ApplicationParameters.Features.StopOnFirstPackageFailure, configuration.Features.StopOnFirstPackageFailure.to_string()), option => configuration.Features.StopOnFirstPackageFailure = option != null ) .Add("exitwhenrebootdetected|exit-when-reboot-detected", "Exit When Reboot Detected - Stop running install, upgrade, or uninstall when a reboot request is detected. Requires '{0}' feature to be turned on. Will exit with either {1} or {2}. Overrides the default feature '{3}' set to '{4}'. Available in 0.10.12+.".format_with (ApplicationParameters.Features.UsePackageExitCodes, ApplicationParameters.ExitCodes.ErrorFailNoActionReboot, ApplicationParameters.ExitCodes.ErrorInstallSuspend, ApplicationParameters.Features.ExitOnRebootDetected, configuration.Features.ExitOnRebootDetected.to_string()), option => configuration.Features.ExitOnRebootDetected = option != null ) .Add("ignoredetectedreboot|ignore-detected-reboot", "Ignore Detected Reboot - Ignore any detected reboots if found. Overrides the default feature '{0}' set to '{1}'. Available in 0.10.12+.".format_with (ApplicationParameters.Features.ExitOnRebootDetected, configuration.Features.ExitOnRebootDetected.to_string()), option => { if (option != null) { configuration.Features.ExitOnRebootDetected = false; } }) .Add("disable-repository-optimizations|disable-package-repository-optimizations", "Disable Package Repository Optimizations - Do not use optimizations for reducing bandwidth with repository queries during package install/upgrade/outdated operations. Should not generally be used, unless a repository needs to support older methods of query. When used, this makes queries similar to the way they were done in Chocolatey v0.10.11 and before. Overrides the default feature '{0}' set to '{1}'. Available in 0.10.14+.".format_with (ApplicationParameters.Features.UsePackageRepositoryOptimizations, configuration.Features.UsePackageRepositoryOptimizations.to_string()), option => { if (option != null) { configuration.Features.UsePackageRepositoryOptimizations = false; } }) ; //todo: package name can be a url / installertype }
public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Install Command"); this.Log().Info(@" Installs a package or a list of packages (sometimes specified as a packages.config). Some may prefer to use `cinst` as a shortcut for `choco install`. NOTE: 100% compatible with older chocolatey client (0.9.8.32 and below) with options and switches. Add `-y` for previous behavior with no prompt. In most cases you can still pass options and switches with one dash (`-`). For more details, see the command reference (`choco -?`). "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Usage"); "chocolatey".Log().Info(@" choco install <pkg|packages.config> [<pkg2> <pkgN>] [<options/switches>] cinst <pkg|packages.config> [<pkg2> <pkgN>] [<options/switches>] NOTE: `all` is a special package keyword that will allow you to install all packages from a custom feed. Will not work with Chocolatey default feed. THIS IS NOT YET REIMPLEMENTED. NOTE: Any package name ending with .config is considered a 'packages.config' file. Please see https://bit.ly/packages_config NOTE: Chocolatey Pro / Business builds on top of a great open source experience with quite a few features that enhance the your use of the community package repository (when using Pro), and really enhance the Chocolatey experience all around. If you are an organization looking for a better ROI, look no further than Business - automatic package creation from installer files, automatic recompile support, runtime malware protection, private CDN download cache, synchronize with Programs and Features, etc - https://chocolatey.org/compare. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Examples"); "chocolatey".Log().Info(@" choco install sysinternals choco install notepadplusplus googlechrome atom 7zip choco install notepadplusplus --force --force-dependencies choco install notepadplusplus googlechrome atom 7zip -dvfy choco install git -y --params=""'/GitAndUnixToolsOnPath /NoAutoCrlf'"" choco install git -y --params=""'/GitAndUnixToolsOnPath /NoAutoCrlf'"" --install-arguments=""'/DIR=C:\git'"" # Params are package parameters, passed to the package # Install args are installer arguments, appended to the silentArgs # in the package for the installer itself choco install nodejs.install --version 0.10.35 choco install git -s ""'https://somewhere/out/there'"" choco install git -s ""'https://somewhere/protected'"" -u user -p pass Choco can also install directly from a nuspec/nupkg file. This aids in testing packages: choco install <path/to/nuspec> choco install <path/to/nupkg> Install multiple versions of a package using -m (AllowMultiple versions) choco install ruby --version 1.9.3.55100 -my choco install ruby --version 2.0.0.59800 -my choco install ruby --version 2.1.5 -my What is `-my`? See option bundling in the command reference (`choco -?`). NOTE: All of these will add to PATH variable. We'll be adding a special option to not allow PATH changes. Until then you will need to manually go modify Path to just one Ruby and then use something like uru (https://bitbucket.org/jonforums/uru) or pik (https://community.chocolatey.org/packages/pik) to switch between versions. NOTE: See scripting in the command reference (`choco -?`) for how to write proper scripts and integrations. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Exit Codes"); "chocolatey".Log().Info(@" Exit codes that normally result from running this command. Normal: - 0: operation was successful, no issues detected - -1 or 1: an error has occurred Package Exit Codes: - 1641: success, reboot initiated - 3010: success, reboot required - other (not listed): likely an error has occurred In addition to normal exit codes, packages are allowed to exit with their own codes when the feature '{0}' is turned on. Uninstall command has additional valid exit codes. Available in v0.9.10+. Reboot Exit Codes: - 350: pending reboot detected, no action has occurred - 1604: install suspended, incomplete In addition to the above exit codes, you may also see reboot exit codes when the feature '{1}' is turned on. It typically requires the feature '{0}' to also be turned on to work properly. Available in v0.10.12+. ".format_with(ApplicationParameters.Features.UsePackageExitCodes, ApplicationParameters.Features.ExitOnRebootDetected)); "chocolatey".Log().Info(ChocolateyLoggers.Important, "See It In Action"); "chocolatey".Log().Info(@" Chocolatey FOSS install showing tab completion and `refreshenv` (a way to update environment variables without restarting the shell). FOSS install in action: https://raw.githubusercontent.com/wiki/chocolatey/choco/images/gifs/choco_install.gif Chocolatey Professional showing private download cache and virus scan protection. Pro install in action: https://raw.githubusercontent.com/wiki/chocolatey/choco/images/gifs/chocopro_install_stopped.gif "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Packages.config"); "chocolatey".Log().Info(@" Alternative to PackageName. This is a list of packages in an xml manifest for Chocolatey to install. This is like the packages.config that NuGet uses except it also adds other options and switches. This can also be the path to the packages.config file if it is not in the current working directory. NOTE: The filename is only required to end in .config, the name is not required to be packages.config. <?xml version=""1.0"" encoding=""utf-8""?> <packages> <package id=""apackage"" /> <package id=""anotherPackage"" version=""1.1"" /> <package id=""chocolateytestpackage"" version=""0.1"" source=""somelocation"" /> <package id=""alloptions"" version=""0.1.1"" source=""https://somewhere/api/v2/"" installArguments="""" packageParameters="""" forceX86=""false"" allowMultipleVersions=""false"" ignoreDependencies=""false"" /> </packages> "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Alternative Sources"); "chocolatey".Log().Info(@" Available in 0.9.10+. Ruby This specifies the source is Ruby Gems and that we are installing a gem. If you do not have ruby installed prior to running this command, the command will install that first. e.g. `choco install compass -source ruby` WebPI This specifies the source is Web PI (Web Platform Installer) and that we are installing a WebPI product, such as IISExpress. If you do not have the Web PI command line installed, it will install that first and then the product requested. e.g. `choco install IISExpress --source webpi` Cygwin This specifies the source is Cygwin and that we are installing a cygwin package, such as bash. If you do not have Cygwin installed, it will install that first and then the product requested. e.g. `choco install bash --source cygwin` Python This specifies the source is Python and that we are installing a python package, such as Sphinx. If you do not have easy_install and Python installed, it will install those first and then the product requested. e.g. `choco install sphinx --source python` Windows Features This specifies that the source is a Windows Feature and we should install via the Deployment Image Servicing and Management tool (DISM) on the local machine. e.g. `choco install IIS-WebServerRole --source windowsfeatures` "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Resources"); "chocolatey".Log().Info(@" * How-To: A complete example of how you can use the PackageParameters argument when creating a Chocolatey Package can be seen at https://docs.chocolatey.org/en-us/guides/create/parse-packageparameters-argument * One may want to override the default installation directory of a piece of software. See https://docs.chocolatey.org/en-us/getting-started#overriding-default-install-directory-or-other-advanced-install-concepts. "); "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); "chocolatey".Log().Info(@" NOTE: Options and switches apply to all items passed, so if you are installing multiple packages, and you use `--version=1.0.0`, it is going to look for and try to install version 1.0.0 of every package passed. So please split out multiple package calls when wanting to pass specific options. "); }
public ConcurrentDictionary <string, PackageResult> upgrade_noop(ChocolateyConfiguration config, Action <PackageResult> continueAction) { this.Log().Warn(ChocolateyLoggers.Important, "{0} does not implement upgrade".format_with(APP_NAME)); return(new ConcurrentDictionary <string, PackageResult>(StringComparer.InvariantCultureIgnoreCase)); }
public void uninstall_noop(ChocolateyConfiguration config, Action <PackageResult> continueAction) { this.Log().Warn(ChocolateyLoggers.Important, "{0} does not implement uninstall".format_with(APP_NAME)); }
public virtual void noop(ChocolateyConfiguration configuration) { _packageService.install_noop(configuration); }
public virtual void handle_additional_argument_parsing(IList <string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); if (unparsedArguments.Count > 1) { throw new ApplicationException("A single sources command must be listed. Please see the help menu for those commands"); } var command = SourceCommandType.unknown; string unparsedCommand = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault(); Enum.TryParse(unparsedCommand, true, out command); if (command == SourceCommandType.unknown) { if (!string.IsNullOrWhiteSpace(unparsedCommand)) { this.Log().Warn("Unknown command {0}. Setting to list.".format_with(unparsedCommand)); } command = SourceCommandType.list; } configuration.SourceCommand.Command = command; }
public bool run_action(ChocolateyConfiguration configuration, PackageResult packageResult, CommandNameType command) { var installerRun = false; var file = "chocolateyInstall.ps1"; switch (command) { case CommandNameType.uninstall: file = "chocolateyUninstall.ps1"; break; } var packageDirectory = packageResult.InstallLocation; if (packageDirectory.is_equal_to(ApplicationParameters.InstallLocation) || packageDirectory.is_equal_to(ApplicationParameters.PackagesLocation)) { packageResult.Messages.Add( new ResultMessage( ResultType.Error, "Install location is not specific enough, cannot run PowerShell script:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation) ) ); return(false); } if (!_fileSystem.directory_exists(packageDirectory)) { packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Package install not found:'{0}'".format_with(packageDirectory))); return(installerRun); } var powershellScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).Where(p => !p.to_lower().contains("\\templates\\")); if (powershellScript.Count() != 0) { var chocoPowerShellScript = powershellScript.FirstOrDefault(); var failure = false; //todo: this is here for any possible compatibility issues. Should be reviewed and removed. ConfigurationBuilder.set_environment_variables(configuration); var package = packageResult.Package; Environment.SetEnvironmentVariable("chocolateyPackageName", package.Id); Environment.SetEnvironmentVariable("packageName", package.Id); Environment.SetEnvironmentVariable("chocolateyPackageVersion", package.Version.to_string()); Environment.SetEnvironmentVariable("packageVersion", package.Version.to_string()); Environment.SetEnvironmentVariable("chocolateyPackageFolder", packageDirectory); Environment.SetEnvironmentVariable("packageFolder", packageDirectory); Environment.SetEnvironmentVariable("installArguments", configuration.InstallArguments); Environment.SetEnvironmentVariable("installerArguments", configuration.InstallArguments); Environment.SetEnvironmentVariable("chocolateyInstallArguments", configuration.InstallArguments); Environment.SetEnvironmentVariable("packageParameters", configuration.PackageParameters); Environment.SetEnvironmentVariable("chocolateyPackageParameters", configuration.PackageParameters); if (configuration.ForceX86) { Environment.SetEnvironmentVariable("chocolateyForceX86", "true"); } if (configuration.OverrideArguments) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } if (configuration.NotSilent) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } //todo:if (configuration.NoOutput) //{ // Environment.SetEnvironmentVariable("ChocolateyEnvironmentQuiet","true"); //} if (package.IsDownloadCacheAvailable) { foreach (var downloadCache in package.DownloadCache.or_empty_list_if_null()) { var urlKey = CryptoHashProvider.hash_value(downloadCache.OriginalUrl, CryptoHashProviderType.Sha256).Replace("=", string.Empty); Environment.SetEnvironmentVariable("CacheFile_{0}".format_with(urlKey), downloadCache.FileName); Environment.SetEnvironmentVariable("CacheChecksum_{0}".format_with(urlKey), downloadCache.Checksum); Environment.SetEnvironmentVariable("CacheChecksumType_{0}".format_with(urlKey), "sha512"); } } this.Log().Debug(ChocolateyLoggers.Important, "Contents of '{0}':".format_with(chocoPowerShellScript)); string chocoPowerShellScriptContents = _fileSystem.read_file(chocoPowerShellScript); this.Log().Debug(chocoPowerShellScriptContents.escape_curly_braces()); bool shouldRun = !configuration.PromptForConfirmation; if (!shouldRun) { this.Log().Info(ChocolateyLoggers.Important, () => "The package {0} wants to run '{1}'.".format_with(package.Id, _fileSystem.get_file_name(chocoPowerShellScript))); this.Log().Info(ChocolateyLoggers.Important, () => "Note: If you don't run this script, the installation will fail."); this.Log().Info(ChocolateyLoggers.Important, () => @"Note: To confirm automatically next time, use '-y' or consider setting 'allowGlobalConfirmation'. Run 'choco feature -h' for more details."); var selection = InteractivePrompt.prompt_for_confirmation(@"Do you want to run the script?", new[] { "yes", "no", "print" }, defaultChoice: null, requireAnswer: true); if (selection.is_equal_to("print")) { this.Log().Info(ChocolateyLoggers.Important, "------ BEGIN SCRIPT ------"); this.Log().Info(() => "{0}{1}{0}".format_with(Environment.NewLine, chocoPowerShellScriptContents.escape_curly_braces())); this.Log().Info(ChocolateyLoggers.Important, "------- END SCRIPT -------"); selection = InteractivePrompt.prompt_for_confirmation(@"Do you want to run this script?", new[] { "yes", "no" }, defaultChoice: null, requireAnswer: true); } if (selection.is_equal_to("yes")) { shouldRun = true; } if (selection.is_equal_to("no")) { Environment.ExitCode = 1; packageResult.Messages.Add(new ResultMessage(ResultType.Error, "User cancelled powershell portion of installation for '{0}'.{1} Specify -n to skip automated script actions.".format_with(powershellScript.FirstOrDefault(), Environment.NewLine))); } } if (shouldRun) { installerRun = true; if (configuration.Features.UsePowerShellHost) { add_assembly_resolver(); } var result = new PowerShellExecutionResults { ExitCode = -1 }; try { result = configuration.Features.UsePowerShellHost ? Execute.with_timeout(configuration.CommandExecutionTimeoutSeconds).command(() => run_host(configuration, chocoPowerShellScript), result) : run_external_powershell(configuration, chocoPowerShellScript); } catch (Exception ex) { this.Log().Error(ex.Message.escape_curly_braces()); result.ExitCode = -1; } if (configuration.Features.UsePowerShellHost) { remove_assembly_resolver(); } if (result.StandardErrorWritten && configuration.Features.FailOnStandardError) { failure = true; } else if (result.StandardErrorWritten && result.ExitCode == 0) { this.Log().Warn( () => @"Only an exit code of non-zero will fail the package by default. Set `--failonstderr` if you want error messages to also fail a script. See `choco -h` for details."); } if (result.ExitCode != 0) { failure = true; } if (failure) { Environment.ExitCode = result.ExitCode; packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Error while running '{0}'.{1} See log for details.".format_with(powershellScript.FirstOrDefault(), Environment.NewLine))); } packageResult.Messages.Add(new ResultMessage(ResultType.Note, "Ran '{0}'".format_with(chocoPowerShellScript))); } } return(installerRun); }
public virtual int count(ChocolateyConfiguration config) { return(list(config).Count()); }
public void handle_additional_argument_parsing(IList <string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); if (unparsedArguments.Count > 1) { throw new ApplicationException("A single features command must be listed. Please see the help menu for those commands"); } var command = FeatureCommandType.unknown; Enum.TryParse(unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault(), true, out command); if (command == FeatureCommandType.unknown) { command = FeatureCommandType.list; } configuration.FeatureCommand.Command = command; }
public void list_noop(ChocolateyConfiguration config) { var args = ExternalCommandArgsBuilder.build_arguments(config, _listArguments); this.Log().Info("Would have run '{0} {1}'".format_with(EXE_PATH.escape_curly_braces(), args.escape_curly_braces())); }
private ICommand find_command(ChocolateyConfiguration config, Container container, bool isConsole, Action <ICommand> parseArgs) { var commands = container.GetAllInstances <ICommand>(); var command = commands.Where((c) => { var attributes = c.GetType().GetCustomAttributes(typeof(CommandForAttribute), false); return(attributes.Cast <CommandForAttribute>().Any(attribute => attribute.CommandName.is_equal_to(config.CommandName))); }).FirstOrDefault(); if (command == null) { //todo add a search among other location/extensions for the command if (!string.IsNullOrWhiteSpace(config.CommandName)) { throw new Exception(@"Could not find a command registered that meets '{0}'. Try choco -? for command reference/help.".format_with(config.CommandName)); } if (isConsole) { Environment.ExitCode = 1; } } else { if (parseArgs != null) { parseArgs.Invoke(command); } if (command.may_require_admin_access()) { warn_when_admin_needs_elevation(config); } set_source_type(config); // guaranteed that all settings are set. EnvironmentSettings.set_environment_variables(config); this.Log().Debug(() => "Configuration: {0}".format_with(config.ToString())); if (isConsole && (config.HelpRequested || config.UnsuccessfulParsing)) { #if DEBUG Console.WriteLine("Press enter to continue..."); Console.ReadKey(); #endif Environment.Exit(config.UnsuccessfulParsing? 1 : 0); } var token = Assembly.GetExecutingAssembly().get_public_key_token(); if (string.IsNullOrWhiteSpace(token) || !token.is_equal_to(ApplicationParameters.OfficialChocolateyPublicKey)) { if (!config.AllowUnofficialBuild) { throw new Exception(@" Custom unofficial builds are not allowed by default. To override this behavior, explicitly set --allow-unofficial. See the help menu (choco -h) for options."); } else { this.Log().Warn(ChocolateyLoggers.Important, @" Chocolatey is not an official build (bypassed with --allow-unofficial). If you are seeing this message and it is not expected, your system may now be in a bad state. Only official builds are to be trusted. " ); } } } return(command); }
public virtual void noop(ChocolateyConfiguration configuration) { _configSettingsService.noop(configuration); }
public int count_run(ChocolateyConfiguration config) { throw new NotImplementedException("Count is not supported for this source runner."); }
private PowerShellExecutionResults run_host(ChocolateyConfiguration config, string chocoPowerShellScript) { // since we control output in the host, always set these true Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); var result = new PowerShellExecutionResults(); string commandToRun = wrap_script_with_module(chocoPowerShellScript, config); var host = new PoshHost(config); this.Log().Debug(() => "Calling built-in PowerShell host with ['{0}']".format_with(commandToRun.escape_curly_braces())); var initialSessionState = InitialSessionState.CreateDefault(); // override system execution policy without accidentally setting it initialSessionState.AuthorizationManager = new AuthorizationManager("choco"); using (var runspace = RunspaceFactory.CreateRunspace(host, initialSessionState)) { runspace.Open(); // this will affect actual execution policy //RunspaceInvoke invoker = new RunspaceInvoke(runspace); //invoker.Invoke("Set-ExecutionPolicy ByPass"); using (var pipeline = runspace.CreatePipeline()) { // The powershell host itself handles the following items: // * Write-Debug // * Write-Host // * Write-Verbose // * Write-Warning // // the two methods below will pick up Write-Output and Write-Error // Write-Output pipeline.Output.DataReady += (sender, args) => { PipelineReader <PSObject> reader = sender as PipelineReader <PSObject>; if (reader != null) { while (reader.Count > 0) { host.UI.WriteLine(reader.Read().to_string().escape_curly_braces()); } } }; // Write-Error pipeline.Error.DataReady += (sender, args) => { PipelineReader <object> reader = sender as PipelineReader <object>; if (reader != null) { while (reader.Count > 0) { host.UI.WriteErrorLine(reader.Read().to_string().escape_curly_braces()); } } }; pipeline.Commands.Add(new Command(commandToRun, isScript: true, useLocalScope: false)); try { pipeline.Invoke(); } catch (RuntimeException ex) { var errorStackTrace = ex.StackTrace; var record = ex.ErrorRecord; if (record != null) { // not available in v1 //errorStackTrace = record.ScriptStackTrace; var scriptStackTrace = record.GetType().GetProperty("ScriptStackTrace"); if (scriptStackTrace != null) { var scriptError = scriptStackTrace.GetValue(record, null).to_string(); if (!string.IsNullOrWhiteSpace(scriptError)) { errorStackTrace = scriptError; } } } this.Log().Error("ERROR: {0}{1}".format_with(ex.Message.escape_curly_braces(), !config.Debug ? string.Empty : "{0} {1}".format_with(Environment.NewLine, errorStackTrace.escape_curly_braces()))); } catch (Exception ex) { // Unfortunately this doesn't print line number and character. It might be nice to get back to those items unless it involves tons of work. this.Log().Error("ERROR: {0}{1}".format_with(ex.Message.escape_curly_braces(), !config.Debug ? string.Empty : "{0} {1}".format_with(Environment.NewLine, ex.StackTrace.escape_curly_braces()))); } if (pipeline.PipelineStateInfo != null) { switch (pipeline.PipelineStateInfo.State) { // disconnected is not available unless the assembly version is at least v3 //case PipelineState.Disconnected: case PipelineState.Running: case PipelineState.NotStarted: case PipelineState.Failed: case PipelineState.Stopping: case PipelineState.Stopped: host.SetShouldExit(1); host.HostException = pipeline.PipelineStateInfo.Reason; break; case PipelineState.Completed: host.SetShouldExit(0); break; } } } } this.Log().Debug("Built-in PowerShell host called with ['{0}'] exited with '{1}'.".format_with(commandToRun.escape_curly_braces(), host.ExitCode)); result.ExitCode = host.ExitCode; result.StandardErrorWritten = host.StandardErrorWritten; return(result); }
public ChocolateyPackageInformationService(IFileSystem fileSystem, IRegistryService registryService, IFilesService filesService, ChocolateyConfiguration config) { _fileSystem = fileSystem; _registryService = registryService; _filesService = filesService; _config = config; }
public void noop(ChocolateyConfiguration configuration) { var templateLocation = _fileSystem.combine_paths(configuration.OutputDirectory ?? _fileSystem.get_current_directory(), configuration.NewCommand.Name); this.Log().Info(() => "Would have generated a new package specification at {0}".format_with(templateLocation)); }
private static void trap_exit_scenarios(ChocolateyConfiguration config) { ExitScenarioHandler.SetHandler(); }
public virtual void handle_additional_argument_parsing(IList <string> unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); }
public void run(ChocolateyConfiguration configuration) { _packageService.list_run(configuration, logResults: true); }
public ConcurrentDictionary <string, PackageResult> uninstall_run(ChocolateyConfiguration config, Action <PackageResult> continueAction) { throw new NotImplementedException("{0} does not implement uninstall".format_with(APP_NAME)); }
public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, PackageResult packageResult, string packageCacheLocation) { //todo: if there is a local package, look to use it in the future if (string.IsNullOrWhiteSpace(key.UninstallString)) { this.Log().Info(" Skipping auto uninstaller - '{0}' does not have an uninstall string.".format_with(!string.IsNullOrEmpty(key.DisplayName.to_string()) ? key.DisplayName.to_string().escape_curly_braces() : "The application")); return; } this.Log().Debug(() => " Preparing uninstall key '{0}' for '{1}'".format_with(key.UninstallString.to_string().escape_curly_braces(), key.DisplayName.to_string().escape_curly_braces())); if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)) { this.Log().Info(" Skipping auto uninstaller - '{0}' appears to have been uninstalled already by other means.".format_with(!string.IsNullOrEmpty(key.DisplayName.to_string()) ? key.DisplayName.to_string().escape_curly_braces() : "The application")); this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.to_string().escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation))); this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))); return; } // split on " /" and " -" for quite a bit more accuracy IList <string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList(); var uninstallExe = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault().trim_safe(); if (uninstallExe.Count(u => u == '"') > 2) { uninstallExe = uninstallExe.Split(new [] { " \"" }, StringSplitOptions.RemoveEmptyEntries).First(); } if (uninstallExe.Count(u => u == ':') > 1) { try { var firstMatch = Regex.Match(uninstallExe, @"\s+\w\:", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); uninstallExe = uninstallExe.Substring(0, firstMatch.Index); } catch (Exception ex) { this.Log().Debug("Error splitting the uninstall string:{0} {1}".format_with(Environment.NewLine, ex.to_string())); } } var uninstallArgs = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty).trim_safe(); uninstallExe = uninstallExe.remove_surrounding_quotes(); this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe)); if (uninstallExe.contains("\\") || uninstallExe.contains("/")) { if (!_fileSystem.file_exists(uninstallExe)) { this.Log().Info(" Skipping auto uninstaller - The uninstaller file no longer exists. \"{0}\"".format_with(uninstallExe)); return; } } IInstaller installer = get_installer_type(key, uninstallExe, uninstallArgs); this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name)); if (key.InstallerType == InstallerType.Msi) { // because sometimes the key is set with /i to allow for modify :/ uninstallArgs = uninstallArgs.Replace("/I{", "/X{"); uninstallArgs = uninstallArgs.Replace("/i{", "/X{"); uninstallArgs = uninstallArgs.Replace("/I ", "/X "); uninstallArgs = uninstallArgs.Replace("/i ", "/X "); } if (!key.HasQuietUninstall) { //todo: ultimately we should merge keys uninstallArgs += " " + installer.build_uninstall_command_arguments(); } this.Log().Debug(() => " Setting up uninstall logging directory at {0}".format_with(packageCacheLocation.escape_curly_braces())); _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(packageCacheLocation)); uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, packageCacheLocation); uninstallArgs = uninstallArgs.Replace(InstallTokens.TEMP_LOCATION, packageCacheLocation); this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs.escape_curly_braces())); if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller)) { if (!config.Information.IsLicensedVersion) { this.Log().Warn(@" Did you know licensed versions of Chocolatey are 95% effective with Automatic Uninstaller due to licensed enhancements and Package Synchronizer? "); } var skipUninstaller = true; var timeout = config.PromptForConfirmation ? 0 : 30; var selection = InteractivePrompt.prompt_for_confirmation( "Uninstall may not be silent (could not detect). Proceed?", new[] { "yes", "no" }, defaultChoice: "no", requireAnswer: true, allowShortAnswer: true, shortPrompt: true, timeoutInSeconds: timeout ); if (selection.is_equal_to("yes")) { skipUninstaller = false; } if (skipUninstaller) { this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists."); this.Log().Warn("If the application was not removed with a chocolateyUninstall.ps1,{0} please remove it from Programs and Features manually.".format_with(Environment.NewLine)); return; } } var exitCode = _commandExecutor.execute( uninstallExe, uninstallArgs.trim_safe(), config.CommandExecutionTimeoutSeconds, (s, e) => { if (e == null || string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces())); }, (s, e) => { if (e == null || string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces())); }, updateProcessPath: false); if (!installer.ValidUninstallExitCodes.Contains(exitCode)) { Environment.ExitCode = exitCode; string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode); this.Log().Error(() => logMessage.escape_curly_braces()); packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage)); } else { this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id)); } }