private string get_script_for_action(PackageResult packageResult, CommandNameType command) { var file = "chocolateyInstall.ps1"; switch (command) { case CommandNameType.uninstall: file = "chocolateyUninstall.ps1"; break; case CommandNameType.upgrade: file = "chocolateyBeforeModify.ps1"; break; } var packageDirectory = packageResult.InstallLocation; var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).Where(p => !p.to_lower().contains("\\templates\\")); if (installScript.Count() != 0) { return(installScript.FirstOrDefault()); } return(string.Empty); }
public string DoOperation( ChocoTestContext testcontext = ChocoTestContext.upgrade_testing_context, Action <ChocolateyConfiguration> confPatch = null, CommandNameType operation = CommandNameType.upgrade, ChocoTestContext packagesContext = ChocoTestContext.packages_for_upgrade_testing, [CallerMemberName] string testFolder = "" ) { string packageName = null; Action <ChocolateyConfiguration> upgradePatch = (conf) => { conf.CommandName = operation.ToString(); conf.PackageNames = conf.Input = "upgradepackage"; if (confPatch != null) { confPatch(conf); } packageName = conf.PackageNames; }; ExecuteConf(testcontext, upgradePatch, packagesContext, Path.Combine(nameof(TestUpgradeCommand), testFolder)); return(packageName); }
public void noop_action(PackageResult packageResult, CommandNameType command) { var chocoInstall = get_script_for_action(packageResult, command); if (!string.IsNullOrEmpty(chocoInstall)) { this.Log().Info("Would have run '{0}':".format_with(_fileSystem.get_file_name(chocoInstall))); this.Log().Warn(_fileSystem.read_file(chocoInstall).escape_curly_braces()); } }
public void noop_action(PackageResult packageResult, CommandNameType command) { var file = "chocolateyInstall.ps1"; switch (command) { case CommandNameType.uninstall: file = "chocolateyUninstall.ps1"; break; } var packageDirectory = packageResult.InstallLocation; var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories); if (installScript.Count != 0) { var chocoInstall = installScript.FirstOrDefault(); this.Log().Info("Would have run '{0}':".format_with(chocoInstall)); this.Log().Warn(_fileSystem.read_file(chocoInstall)); } }
public void noop_action(PackageResult packageResult, CommandNameType command) { var file = "chocolateyInstall.ps1"; switch (command) { case CommandNameType.uninstall: file = "chocolateyUninstall.ps1"; break; } var packageDirectory = packageResult.InstallLocation; var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories); if (installScript.Count() != 0) { var chocoInstall = installScript.FirstOrDefault(); this.Log().Info("Would have run '{0}':".format_with(chocoInstall)); this.Log().Warn(_fileSystem.read_file(chocoInstall).escape_curly_braces()); } }
private string get_script_for_action(PackageResult packageResult, CommandNameType command) { var file = "chocolateyInstall.ps1"; switch (command) { case CommandNameType.uninstall: file = "chocolateyUninstall.ps1"; break; case CommandNameType.upgrade: file = "chocolateyBeforeModify.ps1"; break; } var packageDirectory = packageResult.InstallLocation; var installScript = _fileSystem.get_files(packageDirectory, file, SearchOption.AllDirectories).Where(p => !p.to_lower().contains("\\templates\\")); if (installScript.Count() != 0) { return installScript.FirstOrDefault(); } return string.Empty; }
public CommandForAttribute(CommandNameType commandName) { CommandName = commandName.to_string(); }
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); if (powershellScript.Count() != 0) { var chocoPowerShellScript = powershellScript.FirstOrDefault(); var failure = false; var package = packageResult.Package; Environment.SetEnvironmentVariable(ApplicationParameters.ChocolateyInstallEnvironmentVariableName, ApplicationParameters.InstallLocation); Environment.SetEnvironmentVariable("CHOCOLATEY_VERSION", configuration.Information.ChocolateyVersion); Environment.SetEnvironmentVariable("CHOCOLATEY_VERSION_PRODUCT", configuration.Information.ChocolateyProductVersion); Environment.SetEnvironmentVariable("OS_PLATFORM", configuration.Information.PlatformType.get_description_or_value()); Environment.SetEnvironmentVariable("OS_VERSION", configuration.Information.PlatformVersion.to_string()); Environment.SetEnvironmentVariable("OS_NAME", configuration.Information.PlatformName.to_string()); // experimental until we know if this value returns correctly based on the OS and not the current process. Environment.SetEnvironmentVariable("OS_IS64BIT", configuration.Information.Is64Bit ? "true" : "false"); Environment.SetEnvironmentVariable("IS_ADMIN", configuration.Information.IsUserAdministrator ? "true" : "false"); Environment.SetEnvironmentVariable("IS_PROCESSELEVATED", configuration.Information.IsProcessElevated ? "true" : "false"); 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"); } Environment.SetEnvironmentVariable("TEMP", configuration.CacheLocation); if (configuration.NotSilent) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } if (configuration.Debug) { Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); } if (configuration.Verbose) { Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); } //todo:if (configuration.NoOutput) //{ // Environment.SetEnvironmentVariable("ChocolateyEnvironmentQuiet","true"); //} 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; var exitCode = PowershellExecutor.execute( wrap_script_with_module(chocoPowerShellScript, configuration), _fileSystem, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) return; //inspect for different streams if (e.Data.StartsWith("DEBUG:")) { this.Log().Debug(() => " " + e.Data); } else if (e.Data.StartsWith("WARNING:")) { this.Log().Warn(() => " " + e.Data); } else if (e.Data.StartsWith("VERBOSE:")) { this.Log().Info(ChocolateyLoggers.Verbose, () => " " + e.Data); } else { this.Log().Info(() => " " + e.Data); } }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) return; if (e.Data.is_equal_to(OPERATION_COMPLETED_SUCCESSFULLY)) { this.Log().Info(() => " " + e.Data); } else { failure = true; this.Log().Error(() => " " + e.Data); } }); if (exitCode != 0) { failure = true; } if (failure) { Environment.ExitCode = 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 void handle_package_result(PackageResult packageResult, ChocolateyConfiguration config, CommandNameType commandName) { var pkgInfo = _packageInfoService.get_package_information(packageResult.Package); if (config.AllowMultipleVersions) { pkgInfo.IsSideBySide = true; } if (packageResult.Success && config.Information.PlatformType == PlatformType.Windows) { if (!config.SkipPackageInstallProvider) { var before = _registryService.get_installer_keys(); var powerShellRan = _powershellService.install(config, packageResult); if (powerShellRan) { //todo: prevent reboots } var difference = _registryService.get_differences(before, _registryService.get_installer_keys()); if (difference.RegistryKeys.Count != 0) { //todo v1 - determine the installer type and write it to the snapshot //todo v1 - note keys passed in pkgInfo.RegistrySnapshot = difference; var key = difference.RegistryKeys.FirstOrDefault(); if (key != null && key.HasQuietUninstall) { pkgInfo.HasSilentUninstall = true; } } } if (packageResult.Success) { _shimgenService.install(config, packageResult); } } else { if (config.Information.PlatformType != PlatformType.Windows) { this.Log().Info(ChocolateyLoggers.Important, () => " Skipping Powershell and shimgen portions of the install due to non-Windows."); } } if (packageResult.Success) { handle_extension_packages(config, packageResult); } _packageInfoService.save_package_information(pkgInfo); ensure_bad_package_path_is_clean(config, packageResult); if (!packageResult.Success) { this.Log().Error(ChocolateyLoggers.Important, "{0} {1} not successful.".format_with(packageResult.Name, commandName.to_string())); handle_unsuccessful_operation(config, packageResult, movePackageToFailureLocation: true, attemptRollback: true); return; } remove_rollback_if_exists(packageResult); this.Log().Info(ChocolateyLoggers.Important, " {0} has been {1}ed successfully.".format_with(packageResult.Name, commandName.to_string())); }
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); 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"); //} 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); 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 bool run_action(ChocolateyConfiguration configuration, PackageResult packageResult, CommandNameType command) { var installerRun = false; 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 chocoPowerShellScript = get_script_for_action(packageResult, command); if (!string.IsNullOrEmpty(chocoPowerShellScript)) { var failure = false; var package = packageResult.Package; prepare_powershell_environment(package, configuration, packageDirectory); 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:"); this.Log().Info(ChocolateyLoggers.Important, () => @"choco feature enable -n allowGlobalConfirmation"); var selection = InteractivePrompt.prompt_for_confirmation(@"Do you want to run the script?", new[] { "yes", "no", "print" }, defaultChoice: null, requireAnswer: true, allowShortAnswer: true, shortPrompt: 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, allowShortAnswer: true, shortPrompt: true ); } if (selection.is_equal_to("yes")) { shouldRun = true; } if (selection.is_equal_to("no")) { //MSI ERROR_INSTALL_USEREXIT - 1602 - https://support.microsoft.com/en-us/kb/304888 / https://msdn.microsoft.com/en-us/library/aa376931.aspx //ERROR_INSTALL_CANCEL - 15608 - https://msdn.microsoft.com/en-us/library/windows/desktop/ms681384.aspx Environment.ExitCode = 15608; packageResult.Messages.Add(new ResultMessage(ResultType.Error, "User canceled powershell portion of installation for '{0}'.{1} Specify -n to skip automated script actions.".format_with(chocoPowerShellScript, 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, null), 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) { Environment.ExitCode = result.ExitCode; packageResult.ExitCode = result.ExitCode; } // 0 - most widely used success exit code // MSI valid exit codes // 1605 - (uninstall) - the product is not found, could have already been uninstalled // 1614 (uninstall) - the product is uninstalled // 1641 - restart initiated // 3010 - restart required var validExitCodes = new List <int> { 0, 1605, 1614, 1641, 3010 }; if (!validExitCodes.Contains(result.ExitCode)) { failure = true; } if (!configuration.Features.UsePackageExitCodes) { Environment.ExitCode = failure ? 1 : 0; } if (failure) { packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Error while running '{0}'.{1} See log for details.".format_with(chocoPowerShellScript, Environment.NewLine))); } packageResult.Messages.Add(new ResultMessage(ResultType.Note, "Ran '{0}'".format_with(chocoPowerShellScript))); } } return(installerRun); }
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 (!_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); if (powershellScript.Count != 0) { var chocoPowerShellScript = powershellScript.FirstOrDefault(); var failure = false; var package = packageResult.Package; Environment.SetEnvironmentVariable("CHOCOLATEY_VERSION", configuration.Information.ChocolateyVersion); Environment.SetEnvironmentVariable("OS_TYPE", configuration.Information.PlatformType.get_description_or_value()); Environment.SetEnvironmentVariable("OS_VERSION", configuration.Information.PlatformVersion.to_string()); // experimental until we know if this value returns correctly based on the OS and not the current process. Environment.SetEnvironmentVariable("OS_IS64BIT", configuration.Information.Is64Bit ? "true":"false"); Environment.SetEnvironmentVariable("chocolateyPackageName", package.Id); Environment.SetEnvironmentVariable("chocolateyPackageVersion", package.Version.to_string()); Environment.SetEnvironmentVariable("chocolateyPackageFolder", ApplicationParameters.PackagesLocation); Environment.SetEnvironmentVariable("installerArguments", configuration.InstallArguments); Environment.SetEnvironmentVariable("chocolateyPackageParameters", configuration.PackageParameters); if (configuration.ForceX86) { Environment.SetEnvironmentVariable("chocolateyForceX86", "true"); } if (configuration.OverrideArguments) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } if (!string.IsNullOrWhiteSpace(configuration.CacheLocation)) { //refactor - this is possibly temporary until we get all things running Posh into here Environment.SetEnvironmentVariable("TEMP", configuration.CacheLocation); } //verify how not silent is passed //if (configuration.NotSilent) //{ // Environment.SetEnvironmentVariable("installerArguments", " "); // Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); //} if (configuration.Debug) { Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); } if (configuration.Verbose) { Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); } //todo:if (configuration.NoOutput) //{ // Environment.SetEnvironmentVariable("ChocolateyEnvironmentQuiet","true"); //} this.Log().Debug(ChocolateyLoggers.Important, "Contents of '{0}':".format_with(chocoPowerShellScript)); string chocoPowerShellScriptContents = _fileSystem.read_file(chocoPowerShellScript).escape_curly_braces(); this.Log().Debug(chocoPowerShellScriptContents); bool shouldRun = !configuration.PromptForConfirmation; if (!shouldRun) { this.Log().Info(ChocolateyLoggers.Important, () => " Found '{0}':".format_with(_fileSystem.get_file_name(chocoPowerShellScript))); this.Log().Info(() => "{0}{1}{0}".format_with(Environment.NewLine, chocoPowerShellScriptContents)); var selection = InteractivePrompt.prompt_for_confirmation(" Do you want to run the script?", new[] { "yes", "no", "skip" }, "yes", 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} Use skip to install without run.".format_with(powershellScript.FirstOrDefault(), Environment.NewLine))); } } if (shouldRun) { installerRun = true; var exitCode = PowershellExecutor.execute( wrap_command_with_module(chocoPowerShellScript), _fileSystem, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } //inspect for different streams if (e.Data.StartsWith("DEBUG:")) { this.Log().Debug(() => " " + e.Data); } else if (e.Data.StartsWith("WARNING:")) { this.Log().Warn(() => " " + e.Data); } else if (e.Data.StartsWith("VERBOSE:")) { this.Log().Info(ChocolateyLoggers.Verbose, () => " " + e.Data); } else { this.Log().Info(() => " " + e.Data); } }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } failure = true; this.Log().Error(() => " " + e.Data); }); if (failure) { Environment.ExitCode = 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(powershellScript))); } } return(installerRun); }
public bool run_action(ChocolateyConfiguration configuration, PackageResult packageResult, CommandNameType command) { lock (locker) //Installation uses environment variables, which do work only per process. { return(_run_action(configuration, packageResult, 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); 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"); //} 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; var exitCode = PowershellExecutor.execute( wrap_script_with_module(chocoPowerShellScript, configuration), _fileSystem, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } //inspect for different streams if (e.Data.StartsWith("DEBUG:")) { this.Log().Debug(() => " " + e.Data); } else if (e.Data.StartsWith("WARNING:")) { this.Log().Warn(() => " " + e.Data); } else if (e.Data.StartsWith("VERBOSE:")) { this.Log().Info(ChocolateyLoggers.Verbose, () => " " + e.Data); } else { this.Log().Info(() => " " + e.Data); } }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } if (e.Data.is_equal_to(OPERATION_COMPLETED_SUCCESSFULLY) || e.Data.is_equal_to(INITIALIZE_DEFAULT_DRIVES)) { this.Log().Info(() => " " + e.Data); } else { failure = true; this.Log().Error(() => " " + e.Data); } }); if (exitCode != 0) { failure = true; } if (failure) { Environment.ExitCode = 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 HandlePackageResultCompletedMessage(PackageResult packageResult, ChocolateyConfiguration config, CommandNameType commandName) { PackageResult = packageResult; Config = config; CommandName = commandName; }
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); if (powershellScript.Count() != 0) { var chocoPowerShellScript = powershellScript.FirstOrDefault(); var failure = false; var package = packageResult.Package; Environment.SetEnvironmentVariable(ApplicationParameters.ChocolateyInstallEnvironmentVariableName, ApplicationParameters.InstallLocation); Environment.SetEnvironmentVariable("CHOCOLATEY_VERSION", configuration.Information.ChocolateyVersion); Environment.SetEnvironmentVariable("CHOCOLATEY_VERSION_PRODUCT", configuration.Information.ChocolateyProductVersion); Environment.SetEnvironmentVariable("OS_PLATFORM", configuration.Information.PlatformType.get_description_or_value()); Environment.SetEnvironmentVariable("OS_VERSION", configuration.Information.PlatformVersion.to_string()); Environment.SetEnvironmentVariable("OS_NAME", configuration.Information.PlatformName.to_string()); // experimental until we know if this value returns correctly based on the OS and not the current process. Environment.SetEnvironmentVariable("OS_IS64BIT", configuration.Information.Is64Bit ? "true" : "false"); Environment.SetEnvironmentVariable("IS_ADMIN", configuration.Information.IsUserAdministrator ? "true" : "false"); Environment.SetEnvironmentVariable("IS_PROCESSELEVATED", configuration.Information.IsProcessElevated ? "true" : "false"); 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"); } Environment.SetEnvironmentVariable("TEMP", configuration.CacheLocation); if (configuration.NotSilent) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } if (configuration.Debug) { Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); } if (configuration.Verbose) { Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); } //todo:if (configuration.NoOutput) //{ // Environment.SetEnvironmentVariable("ChocolateyEnvironmentQuiet","true"); //} 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} Use skip to install without run.".format_with(powershellScript.FirstOrDefault(), Environment.NewLine))); } } if (shouldRun) { installerRun = true; var exitCode = PowershellExecutor.execute( wrap_script_with_module(chocoPowerShellScript, configuration), _fileSystem, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } //inspect for different streams if (e.Data.StartsWith("DEBUG:")) { this.Log().Debug(() => " " + e.Data); } else if (e.Data.StartsWith("WARNING:")) { this.Log().Warn(() => " " + e.Data); } else if (e.Data.StartsWith("VERBOSE:")) { this.Log().Info(ChocolateyLoggers.Verbose, () => " " + e.Data); } else { this.Log().Info(() => " " + e.Data); } }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } failure = true; this.Log().Error(() => " " + e.Data); }); if (failure) { Environment.ExitCode = 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 bool run_action(ChocolateyConfiguration configuration, PackageResult packageResult, CommandNameType command) { var installerRun = false; 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 chocoPowerShellScript = get_script_for_action(packageResult, command); if (!string.IsNullOrEmpty(chocoPowerShellScript)) { var failure = false; var package = packageResult.Package; prepare_powershell_environment(package, configuration, packageDirectory); 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, allowShortAnswer: true, shortPrompt: 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, allowShortAnswer: true, shortPrompt: 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(chocoPowerShellScript, 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, null), 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) { Environment.ExitCode = result.ExitCode; packageResult.ExitCode = result.ExitCode; } // 0 - most widely used success exit code // MSI valid exit codes // 1605 - (uninstall) - the product is not found, could have already been uninstalled // 1614 (uninstall) - the product is uninstalled // 1641 - restart initiated // 3010 - restart required var validExitCodes = new List<int> { 0, 1605, 1614, 1641, 3010 }; if (!validExitCodes.Contains(result.ExitCode)) { failure = true; } if (failure) { packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Error while running '{0}'.{1} See log for details.".format_with(chocoPowerShellScript, Environment.NewLine))); } packageResult.Messages.Add(new ResultMessage(ResultType.Note, "Ran '{0}'".format_with(chocoPowerShellScript))); } } return installerRun; }
public bool run_action(ChocolateyConfiguration configuration, PackageResult packageResult, CommandNameType command) { var installerRun = false; 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 chocoPowerShellScript = get_script_for_action(packageResult, command); if (!string.IsNullOrEmpty(chocoPowerShellScript)) { var failure = false; 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, allowShortAnswer: true, shortPrompt: 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, allowShortAnswer: true, shortPrompt: 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(chocoPowerShellScript, 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) { Environment.ExitCode = result.ExitCode; packageResult.ExitCode = result.ExitCode; } // 0 - most widely used success exit code // MSI valid exit codes // 1605 - (uninstall) - the product is not found, could have already been uninstalled // 1614 (uninstall) - the product is uninstalled // 1641 - restart initiated // 3010 - restart required var validExitCodes = new List <int> { 0, 1605, 1614, 1641, 3010 }; if (!validExitCodes.Contains(result.ExitCode)) { failure = true; } if (failure) { packageResult.Messages.Add(new ResultMessage(ResultType.Error, "Error while running '{0}'.{1} See log for details.".format_with(chocoPowerShellScript, Environment.NewLine))); } packageResult.Messages.Add(new ResultMessage(ResultType.Note, "Ran '{0}'".format_with(chocoPowerShellScript))); } } return(installerRun); }
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); 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"); //} 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); 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 void handle_package_result(PackageResult packageResult, ChocolateyConfiguration config, CommandNameType commandName) { var pkgInfo = _packageInfoService.get_package_information(packageResult.Package); if (config.AllowMultipleVersions) { pkgInfo.IsSideBySide = true; } if (packageResult.Success && config.Information.PlatformType == PlatformType.Windows) { if (!config.SkipPackageInstallProvider) { var before = _registryService.get_installer_keys(); var powerShellRan = _powershellService.install(config, packageResult); if (powerShellRan) { // we don't care about the exit code if (config.Information.PlatformType == PlatformType.Windows) { CommandExecutor.execute_static("shutdown", "/a", config.CommandExecutionTimeoutSeconds, _fileSystem.get_current_directory(), (s, e) => { }, (s, e) => { }, false); } } var difference = _registryService.get_differences(before, _registryService.get_installer_keys()); if (difference.RegistryKeys.Count != 0) { //todo v1 - determine the installer type and write it to the snapshot //todo v1 - note keys passed in pkgInfo.RegistrySnapshot = difference; var key = difference.RegistryKeys.FirstOrDefault(); if (key != null && key.HasQuietUninstall) { pkgInfo.HasSilentUninstall = true; } } } _configTransformService.run(packageResult, config); pkgInfo.FilesSnapshot = _filesService.capture_package_files(packageResult, config); if (packageResult.Success) { _shimgenService.install(config, packageResult); } } else { if (config.Information.PlatformType != PlatformType.Windows) { this.Log().Info(ChocolateyLoggers.Important, () => " Skipping Powershell and shimgen portions of the install due to non-Windows."); } } if (packageResult.Success) { handle_extension_packages(config, packageResult); } _packageInfoService.save_package_information(pkgInfo); ensure_bad_package_path_is_clean(config, packageResult); if (!packageResult.Success) { this.Log().Error(ChocolateyLoggers.Important, "The {0} of {1} was NOT successful.".format_with(commandName.to_string(), packageResult.Name)); handle_unsuccessful_operation(config, packageResult, movePackageToFailureLocation: true, attemptRollback: true); return; } remove_rollback_if_exists(packageResult); this.Log().Info(ChocolateyLoggers.Important, " The {0} of {1} was successful.".format_with(commandName.to_string(), packageResult.Name)); }