private string get_package_install_directory(PackageResult packageResult) { if (packageResult == null) return null; var installDirectory = packageResult.InstallLocation; return package_install_directory_is_correct(installDirectory, logMessage => packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage))) ? installDirectory : null; }
public AddInInstalledEventArgs(AddInPackage package, PackageResult result, string installationPath, string packagePath) { this.Package = package; this.Result = result; this.InstallationPath = installationPath; this.PackagePath = packagePath; }
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 install(ChocolateyConfiguration configuration, PackageResult packageResult) { _fileSystem.create_directory_if_not_exists(ApplicationParameters.ShimsLocation); if (packageResult.InstallLocation.is_equal_to(ApplicationParameters.InstallLocation) || packageResult.InstallLocation.is_equal_to(ApplicationParameters.PackagesLocation)) { var logMessage = "Install location is not specific enough, cannot run shimgen:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation); packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); this.Log().Error(logMessage.escape_curly_braces()); return; } //gather all .exes in the folder var exeFiles = _fileSystem.get_files(packageResult.InstallLocation, pattern: "*.exe", option: SearchOption.AllDirectories); foreach (string file in exeFiles.or_empty_list_if_null()) { if (_fileSystem.file_exists(file + ".ignore")) continue; bool isGui = _fileSystem.file_exists(file + ".gui"); //todo: v2 be able to determine gui automatically var args = ExternalCommandArgsBuilder.build_arguments(configuration, _shimGenArguments); var shimLocation = _fileSystem.combine_paths(ApplicationParameters.ShimsLocation, _fileSystem.get_file_name(file)); var argsForPackage = args.Replace(PATH_TOKEN, file.Replace(ApplicationParameters.InstallLocation, "..\\")).Replace(OUTPUT_TOKEN, shimLocation).Replace(ICON_PATH_TOKEN, file); if (isGui) { argsForPackage += " --gui"; } var exitCode = _commandExecutor.execute( _shimGenExePath, argsForPackage, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) return; this.Log().Debug(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces())); }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) return; this.Log().Error(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces())); }, updateProcessPath: true ); if (exitCode != 0) { Environment.ExitCode = exitCode; } else { this.Log().Info(() => " ShimGen has successfully created a {0}shim for {1}".format_with(isGui ? "gui " : string.Empty, _fileSystem.get_file_name(file))); this.Log().Debug(() => " Created: {0}{1} Targeting: {2}{1} IsGui:{3}{1}".format_with(shimLocation, Environment.NewLine, file, isGui)); } } }
public PackageFiles capture_package_files(PackageResult packageResult, ChocolateyConfiguration config) { if (packageResult == null) return new PackageFiles(); var installDirectory = packageResult.InstallLocation; if (installDirectory.is_equal_to(ApplicationParameters.InstallLocation) || installDirectory.is_equal_to(ApplicationParameters.PackagesLocation)) { var logMessage = "Install location is not specific enough, cannot capture files:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation); packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); this.Log().Error(logMessage); return null; } return capture_package_files(installDirectory, config); }
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 GenericSvcResult ActivateService(ProvisioningContext context) { GenericSvcResult result = new GenericSvcResult(); // SaveObjectState(SERVICE_INFO, context.ServiceInfo); // SaveObjectState(CONSUMER_INFO, context.ConsumerInfo); // concretize service to be provisioned HostingPackageSvc packageSvc = (HostingPackageSvc)context.ServiceInfo; // try { // TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_ACTIVATE); // LOG INFO TaskManager.Write(START_ACTIVATION_MSG); TaskManager.WriteParameter(USERNAME_PARAM, context.ConsumerInfo[ContractAccount.USERNAME]); TaskManager.WriteParameter(SVC_PARAM, context.ServiceInfo.ServiceName); TaskManager.WriteParameter(SVC_ID_PARAM, context.ServiceInfo.ServiceId); TaskManager.UpdateParam(SystemTaskParams.PARAM_SEND_EMAIL, context.SendEmail); // 0. Do security checks if (!CheckOperationClientPermissions(result)) { // LOG ERROR TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // EXIT return(result); } // if (!CheckOperationClientStatus(result)) { // LOG ERROR TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // EXIT return(result); } // 1. Hosting package is just ordered if (context.ServiceInfo.Status == ServiceStatus.Ordered && context.ContractInfo.CustomerId > 0) { // LOG INFO TaskManager.Write(CREATE_PCKG_MSG); // create new package PackageResult apiResult = PackageController.AddPackage(context.ContractInfo.CustomerId, packageSvc.PlanId, packageSvc.ServiceName, String.Empty, (int)packageSvc.InitialStatus, DateTime.Now, true, true); // failed to instantiate package if (apiResult.Result <= 0) { result.ResultCode = apiResult.Result; // result.Succeed = false; // LOG ERROR TaskManager.WriteError(CREATE_PCKG_ERROR_MSG); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // EXIT return(result); } // save result PackageId packageSvc.PackageId = apiResult.Result; } else // 2. Package requires only to update its status { // LOG INFO TaskManager.Write(START_ACTIVATION_MSG); // int apiResult = PackageController.ChangePackageStatus(packageSvc.PackageId, PackageStatus.Active, false); // if (apiResult < 0) { result.ResultCode = apiResult; // result.Succeed = false; // LOG ERROR TaskManager.WriteError(ERROR_ACTIVATE_PCKG_MSG); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // EXIT return(result); } } // check user role if (context.ContractInfo.CustomerId > 0) { UserInfo user = UserController.GetUserInternally(context.ContractInfo.CustomerId); // check user status // if (user.Status != UserStatus.Active) { // LOG INFO TaskManager.Write(START_USR_ACTIVATION_MSG); // trying to change user status int userResult = UserController.ChangeUserStatus(context.ContractInfo.CustomerId, UserStatus.Active); // failed to activate user account if (userResult < 0) { result.ResultCode = userResult; // result.Succeed = false; // LOG ERROR TaskManager.WriteError(ERROR_USR_ACTIVATION_MSG); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // ROLLBACK CHANGES RollbackOperation(result.ResultCode); // EXIT return(result); } } // check user role if (user.Role != packageSvc.UserRole) { // LOG INFO TaskManager.Write(START_CHANGE_USR_ROLE_MSG); // user.Role = packageSvc.UserRole; // trying to change user role int roleResult = UserController.UpdateUser(user); // failed to change user role if (roleResult < 0) { result.ResultCode = roleResult; // result.Succeed = false; // TaskManager.WriteError(ERROR_CHANGE_USR_ROLE_MSG); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // ROLLBACK CHANGES RollbackOperation(result.ResultCode); // EXIT return(result); } } } // update plan status if necessary if (packageSvc.Status != ServiceStatus.Active) { // change service status to active packageSvc.Status = ServiceStatus.Active; // put data into metabase int svcResult = UpdateServiceInfo(packageSvc); // error updating svc details if (svcResult < 0) { result.ResultCode = svcResult; // result.Succeed = false; // ROLLBACK CHANGES RollbackOperation(packageSvc.PackageId); // LOG ERROR TaskManager.WriteError(ERROR_SVC_UPDATE_MSG); TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode); // EXIT return(result); } } // SetOutboundParameters(context); // LOG INFO TaskManager.Write(PCKG_PROVISIONED_MSG); // result.Succeed = true; } catch (Exception ex) { // TaskManager.WriteError(ex); // ROLLBACK CHANGES RollbackOperation(packageSvc.PackageId); // result.Succeed = false; // result.Error = ex.Message; } finally { // complete task TaskManager.CompleteTask(); } // return(result); }
public void run(PackageResult packageResult, ChocolateyConfiguration config) { if (!config.Features.AutoUninstaller) { this.Log().Info(" Skipping auto uninstaller - AutoUninstaller feature is not enabled."); return; } var pkgInfo = _packageInfoService.get_package_information(packageResult.Package); if (pkgInfo.RegistrySnapshot == null) { this.Log().Info(" Skipping auto uninstaller - No registry snapshot."); return; } var registryKeys = pkgInfo.RegistrySnapshot.RegistryKeys; if (registryKeys == null || registryKeys.Count == 0) { this.Log().Info(" Skipping auto uninstaller - No registry keys in snapshot."); return; } this.Log().Info(" Running auto uninstaller..."); if (WaitForCleanup) { this.Log().Debug("Sleeping for {0} seconds to allow Windows to finish cleaning up.".format_with(SLEEP_TIME)); Thread.Sleep((int)TimeSpan.FromSeconds(SLEEP_TIME).TotalMilliseconds); } foreach (var key in registryKeys.or_empty_list_if_null()) { this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString.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 - The application appears to have been uninstalled already by other means."); this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.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))); continue; } // 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(); var uninstallArgs = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty); uninstallExe = uninstallExe.remove_surrounding_quotes(); this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe)); IInstaller installer = new CustomInstaller(); switch (key.InstallerType) { case InstallerType.Msi: installer = new MsiInstaller(); break; case InstallerType.InnoSetup: installer = new InnoSetupInstaller(); break; case InstallerType.Nsis: installer = new NsisInstaller(); break; case InstallerType.InstallShield: installer = new InstallShieldInstaller(); break; } 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(); } var logLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), "chocolatey", pkgInfo.Package.Id, pkgInfo.Package.Version.to_string()); this.Log().Debug(() => " Setting up uninstall logging directory at {0}".format_with(logLocation.escape_curly_braces())); _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(logLocation)); uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, logLocation); this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs.escape_curly_braces())); if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller)) { var skipUninstaller = true; if (config.PromptForConfirmation) { var selection = InteractivePrompt.prompt_for_confirmation( "Uninstall may not be silent (could not detect). Proceed?", new[] { "yes", "no" }, defaultChoice: null, requireAnswer: true, allowShortAnswer: true, shortPrompt: true ); 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)); } } }
public void run(PackageResult packageResult, ChocolateyConfiguration config) { var installDirectory = packageResult != null ? packageResult.InstallLocation : string.Empty; if (string.IsNullOrWhiteSpace(installDirectory) || installDirectory.is_equal_to(ApplicationParameters.InstallLocation) || installDirectory.is_equal_to(ApplicationParameters.PackagesLocation)) { var logMessage = "Install location is not specific enough, cannot capture files:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, installDirectory); if (packageResult != null) packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); this.Log().Error(logMessage); return; } var transformFiles = _fileSystem.get_files(installDirectory, "*" + ApplicationParameters.ConfigFileTransformExtension, SearchOption.AllDirectories); foreach (var transformFile in transformFiles.or_empty_list_if_null()) { this.Log().Debug(() => "Preparing transform for '{0}'".format_with(transformFile)); var targetFileName = _fileSystem.get_file_name(transformFile.Replace(ApplicationParameters.ConfigFileTransformExtension, string.Empty)); // target files must exist, otherwise one is added next to the transform var targetFiles = _fileSystem.get_files(installDirectory, targetFileName, SearchOption.AllDirectories); var targetFilesTest = targetFiles as IList<string> ?? targetFiles.ToList(); if (!targetFilesTest.Any()) { targetFiles = new[] {transformFile.Replace(ApplicationParameters.ConfigFileTransformExtension, string.Empty)}; this.Log().Debug(() => "No matching files found for transform {0}.{1} Creating '{2}'".format_with(_fileSystem.get_file_name(transformFile), Environment.NewLine, targetFiles.FirstOrDefault())); } foreach (var targetFile in targetFilesTest.or_empty_list_if_null()) { FaultTolerance.try_catch_with_logging_exception( () => { // if there is a backup, we need to put it back in place // the user has indicated they are using transforms by putting // the transform file into the folder, so we will override // the replacement of the file and instead pull from the last // backup and let the transform to its thing instead. var backupTargetFile = targetFile.Replace(ApplicationParameters.PackagesLocation, ApplicationParameters.PackageBackupLocation); if (_fileSystem.file_exists(backupTargetFile)) { this.Log().Debug(()=> "Restoring backup configuration file for '{0}'.".format_with(targetFile)); _fileSystem.copy_file(backupTargetFile, targetFile, overwriteExisting: true); } }, "Error replacing backup config file", throwError: false, logWarningInsteadOfError: true); FaultTolerance.try_catch_with_logging_exception( () => { this.Log().Info(() => "Transforming '{0}' with the data from '{1}'".format_with(_fileSystem.get_file_name(targetFile), _fileSystem.get_file_name(transformFile))); using (var transformation = new XmlTransformation(_fileSystem.read_file(transformFile), isTransformAFile: false, logger: null)) { using (var document = new XmlTransformableDocument {PreserveWhitespace = true}) { using (var inputStream = _fileSystem.open_file_readonly(targetFile)) { document.Load(inputStream); } bool succeeded = transformation.Apply(document); if (succeeded) { this.Log().Debug(() => "Transform applied successfully for '{0}'".format_with(targetFile)); using (var memoryStream = new MemoryStream()) { document.Save(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); using (var fileStream = _fileSystem.create_file(targetFile)) { memoryStream.CopyTo(fileStream); } } } else { this.Log().Warn(() => "Transform failed for '{0}'".format_with(targetFile)); } } } }, "Error transforming config file"); } } }
public void install_noop(PackageResult packageResult) { noop_action(packageResult, CommandNameType.install); }
private void ensure_bad_package_path_is_clean(ChocolateyConfiguration config, PackageResult packageResult) { try { string badPackageInstallPath = packageResult.InstallLocation.Replace(ApplicationParameters.PackagesLocation, ApplicationParameters.PackageFailuresLocation); if (_fileSystem.directory_exists(badPackageInstallPath)) { _fileSystem.delete_directory(badPackageInstallPath, recursive: true); } } catch (Exception ex) { if (config.Debug) { this.Log().Error(() => "Attempted to delete bad package install path if existing. Had an error:{0}{1}".format_with(Environment.NewLine, ex)); } else { this.Log().Error(() => "Attempted to delete bad package install path if existing. Had an error:{0}{1}".format_with(Environment.NewLine, ex.Message)); } } }
public bool before_modify(ChocolateyConfiguration configuration, PackageResult packageResult) { return(run_action(configuration, packageResult, CommandNameType.upgrade)); }
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; EnvironmentSettings.set_environment_variables(configuration); EnvironmentSettings.update_environment_variables(); 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); // unset variables that may not be updated so they don't get passed again Environment.SetEnvironmentVariable("installArguments", null); Environment.SetEnvironmentVariable("installerArguments", null); Environment.SetEnvironmentVariable("chocolateyInstallArguments", null); Environment.SetEnvironmentVariable("packageParameters", null); Environment.SetEnvironmentVariable("chocolateyPackageParameters", null); Environment.SetEnvironmentVariable("chocolateyInstallOverride", null); // we only want to pass the following args to packages that would apply. // like choco install git -params '' should pass those params to git.install, // but not another package if (!package_is_a_dependency_not_a_virtual(configuration, package.Id)) { this.Log().Debug(ChocolateyLoggers.Verbose, "Setting installer args and package parameters for {0}".format_with(package.Id)); 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.OverrideArguments) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } } if (configuration.ForceX86) { Environment.SetEnvironmentVariable("chocolateyForceX86", "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 void run(PackageResult packageResult, ChocolateyConfiguration config) { var installDirectory = packageResult != null ? packageResult.InstallLocation : string.Empty; if (string.IsNullOrWhiteSpace(installDirectory) || installDirectory.is_equal_to(ApplicationParameters.InstallLocation) || installDirectory.is_equal_to(ApplicationParameters.PackagesLocation)) { var logMessage = "Install location is not specific enough, cannot capture files:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, installDirectory); if (packageResult != null) { packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); } this.Log().Error(logMessage); return; } var transformFiles = _fileSystem.get_files(installDirectory, "*" + ApplicationParameters.ConfigFileTransformExtension, SearchOption.AllDirectories); foreach (var transformFile in transformFiles.or_empty_list_if_null()) { this.Log().Debug(() => "Preparing transform for '{0}'".format_with(transformFile)); var targetFileName = _fileSystem.get_file_name(transformFile.Replace(ApplicationParameters.ConfigFileTransformExtension, string.Empty)); // target files must exist, otherwise one is added next to the transform var targetFiles = _fileSystem.get_files(installDirectory, targetFileName, SearchOption.AllDirectories); var targetFilesTest = targetFiles as IList <string> ?? targetFiles.ToList(); if (!targetFilesTest.Any()) { targetFiles = new[] { transformFile.Replace(ApplicationParameters.ConfigFileTransformExtension, string.Empty) }; this.Log().Debug(() => "No matching files found for transform {0}.{1} Creating '{2}'".format_with(_fileSystem.get_file_name(transformFile), Environment.NewLine, targetFiles.FirstOrDefault())); } foreach (var targetFile in targetFilesTest.or_empty_list_if_null()) { FaultTolerance.try_catch_with_logging_exception( () => { // if there is a backup, we need to put it back in place // the user has indicated they are using transforms by putting // the transform file into the folder, so we will override // the replacement of the file and instead pull from the last // backup and let the transform to its thing instead. var backupTargetFile = targetFile.Replace(ApplicationParameters.PackagesLocation, ApplicationParameters.PackageBackupLocation); if (_fileSystem.file_exists(backupTargetFile)) { this.Log().Debug(() => "Restoring backup configuration file for '{0}'.".format_with(targetFile)); _fileSystem.copy_file(backupTargetFile, targetFile, overwriteExisting: true); } }, "Error replacing backup config file", throwError: false, logWarningInsteadOfError: true); FaultTolerance.try_catch_with_logging_exception( () => { this.Log().Info(() => "Transforming '{0}' with the data from '{1}'".format_with(_fileSystem.get_file_name(targetFile), _fileSystem.get_file_name(transformFile))); using (var transformation = new XmlTransformation(_fileSystem.read_file(transformFile), isTransformAFile: false, logger: null)) { using (var document = new XmlTransformableDocument { PreserveWhitespace = true }) { using (var inputStream = _fileSystem.open_file_readonly(targetFile)) { document.Load(inputStream); } bool succeeded = transformation.Apply(document); if (succeeded) { this.Log().Debug(() => "Transform applied successfully for '{0}'".format_with(targetFile)); using (var memoryStream = new MemoryStream()) { document.Save(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); using (var fileStream = _fileSystem.create_file(targetFile)) { memoryStream.CopyTo(fileStream); } } } else { this.Log().Warn(() => "Transform failed for '{0}'".format_with(targetFile)); } } } }, "Error transforming config file"); } } }
public void before_modify_noop(PackageResult packageResult) { noop_action(packageResult, CommandNameType.upgrade); }
private void remove_rollback_if_exists(PackageResult packageResult) { _nugetService.remove_rollback_directory_if_exists(packageResult.Name); }
private void ensure_bad_package_path_is_clean(ChocolateyConfiguration config, PackageResult packageResult) { if (packageResult.InstallLocation == null) { return; } FaultTolerance.try_catch_with_logging_exception( () => { string badPackageInstallPath = packageResult.InstallLocation.Replace(ApplicationParameters.PackagesLocation, ApplicationParameters.PackageFailuresLocation); if (_fileSystem.directory_exists(badPackageInstallPath)) { _fileSystem.delete_directory(badPackageInstallPath, recursive: true); } }, "Attempted to delete bad package install path if existing. Had an error"); }
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; } } } 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)); }
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; 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 (!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 override void Because() { MockLogger.LogMessagesToConsole = true; Results = Service.uninstall_run(Configuration); _packageResult = Results.FirstOrDefault().Value; }
public async Task <PackageResult> CompilePackageAsync(Assembly assembly, string buildHash, CancellationToken cancellationToken = default) { await Semaphore.WaitAsync(cancellationToken); try { var packageHash = assembly.ComputePackageHash(buildHash); var sdkDir = Path.GetFullPath(Path.Combine(_options.Value.BuildLocation, $"mono-wasm-{buildHash}")); var assemblyLocation = assembly.Location; var assemblyDir = Path.GetDirectoryName(assemblyLocation); if (string.IsNullOrWhiteSpace(assemblyDir)) { throw new DirectoryNotFoundException(assemblyDir); } var outputDir = Path.GetFullPath(Path.Combine(_options.Value.PackageLocation, $"mono-wasm-{packageHash}")); Directory.CreateDirectory(outputDir); Directory.CreateDirectory(_options.Value.PackageLocation); var sb = new StringBuilder(); sb.Append($" --search-path=\"{assemblyDir}\""); // Add specified path 'x' to list of paths used to resolve assemblies sb.Append($" --mono-sdkdir=\"{sdkDir}\""); // Set the mono sdk directory to 'x' sb.Append($" --copy=always"); // Set the type of copy to perform (always|ifnewest) sb.Append($" --out=\"{outputDir}\""); // Set the output directory to 'x' (default to the current directory) sb.Append($" \"{assemblyLocation}\""); // Include {target}.dll as one of the root assemblies ShadowCopyReferencesRecursive(assembly, assemblyDir); var args = sb.ToString(); var fileName = Path.Combine(sdkDir, "packager.exe"); var process = new Process { StartInfo = new ProcessStartInfo(fileName, args) { UseShellExecute = false, WorkingDirectory = "", RedirectStandardError = true, RedirectStandardOutput = true } }; _logger?.LogDebug("Compiling package {PackageHash}", packageHash); _logger?.LogDebug("-------------------------------", packageHash); _logger?.LogDebug("SDK Location: {SdkDir}", sdkDir); _logger?.LogDebug("Assembly Location: {AssemblyLocation}", assemblyLocation); _logger?.LogDebug("Output Location: {OutputLocation}", outputDir); _logger?.LogDebug("-------------------------------", packageHash); _logger?.LogDebug("{Command}", $"packager.exe {args}"); process.Start(); var output = await process.StandardOutput.ReadToEndAsync(); var errors = await process.StandardError.ReadToEndAsync(); if (!string.IsNullOrWhiteSpace(errors)) { _logger?.LogWarning(errors); } if (!string.IsNullOrWhiteSpace(output)) { _logger?.LogDebug(output); } var result = new PackageResult { Successful = true, Errors = errors, Output = output }; return(result); } finally { Semaphore.Release(); } }
public override void Because() { Results = Service.uninstall_run(Configuration); packageResult = Results.FirstOrDefault().Value; }
private void SavePlan() { if (!Page.IsValid) { return; } // gather form info HostingPlanInfo plan = new HostingPlanInfo(); plan.UserId = PanelSecurity.SelectedUserId; plan.PlanId = PanelRequest.PlanID; plan.IsAddon = true; plan.PlanName = txtPlanName.Text; plan.PlanDescription = txtPlanDescription.Text; plan.Available = true; // always available plan.SetupPrice = 0; plan.RecurringPrice = 0; plan.RecurrenceLength = 1; plan.RecurrenceUnit = 2; // month plan.Groups = hostingPlansQuotas.Groups; plan.Quotas = hostingPlansQuotas.Quotas; int planId = PanelRequest.PlanID; if ((PanelRequest.PlanID == 0) || ShouldCopyCurrentHostingAddon()) { // new plan try { planId = ES.Services.Packages.AddHostingPlan(plan); if (planId < 0) { ShowResultMessage(planId); return; } } catch (Exception ex) { ShowErrorMessage("ADDON_ADD_ADDON", ex); return; } } else { // update plan try { PackageResult result = ES.Services.Packages.UpdateHostingPlan(plan); lblMessage.Text = PortalAntiXSS.Encode(GetExceedingQuotasMessage(result.ExceedingQuotas)); if (result.Result < 0) { ShowResultMessage(result.Result); return; } } catch (Exception ex) { ShowErrorMessage("ADDON_UPDATE_ADDON", ex); return; } } // redirect RedirectBack(); }
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 ConcurrentDictionary<string, PackageResult> uninstall_run(ChocolateyConfiguration config, Action<PackageResult> continueAction, bool performAction, Action<PackageResult> beforeUninstallAction = null) { var packageUninstalls = new ConcurrentDictionary<string, PackageResult>(StringComparer.InvariantCultureIgnoreCase); SemanticVersion version = config.Version != null ? new SemanticVersion(config.Version) : null; var packageManager = NugetCommon.GetPackageManager(config, _nugetLogger, installSuccessAction: null, uninstallSuccessAction: (e) => { var pkg = e.Package; "chocolatey".Log().Info(ChocolateyLoggers.Important, " {0} has been successfully uninstalled.".format_with(pkg.Id)); }, addUninstallHandler: true); var loopCount = 0; packageManager.PackageUninstalling += (s, e) => { var pkg = e.Package; // this section fires twice sometimes, like for older packages in a sxs install... var packageResult = packageUninstalls.GetOrAdd(pkg.Id.to_lower() + "." + pkg.Version.to_string(), new PackageResult(pkg, e.InstallPath)); packageResult.InstallLocation = e.InstallPath; string logMessage = "{0}{1} v{2}{3}".format_with(Environment.NewLine, pkg.Id, pkg.Version.to_string(), config.Force ? " (forced)" : string.Empty); if (packageResult.Messages.Count((p) => p.Message == ApplicationParameters.Messages.NugetEventActionHeader) == 0) { packageResult.Messages.Add(new ResultMessage(ResultType.Debug, ApplicationParameters.Messages.NugetEventActionHeader)); "chocolatey".Log().Info(ChocolateyLoggers.Important, logMessage); loopCount = 0; } else { "chocolatey".Log().Debug(ChocolateyLoggers.Important, "Another time through!{0}{1}".format_with(Environment.NewLine, logMessage)); loopCount += 1; } if (loopCount == 10) { this.Log().Warn("Loop detected. Attempting to break out. Check for issues with {0}".format_with(pkg.Id)); return; } // is this the latest version, have you passed --sxs, or is this a side-by-side install? This is the only way you get through to the continue action. var latestVersion = packageManager.LocalRepository.FindPackage(e.Package.Id); var pkgInfo = _packageInfoService.get_package_information(e.Package); if (latestVersion.Version == pkg.Version || config.AllowMultipleVersions || (pkgInfo != null && pkgInfo.IsSideBySide)) { packageResult.Messages.Add(new ResultMessage(ResultType.Debug, ApplicationParameters.Messages.ContinueChocolateyAction)); if (continueAction != null) continueAction.Invoke(packageResult); } else { //todo:allow cleaning of pkgstore files } }; // if we are uninstalling a package and not forcing dependencies, // look to see if the user is missing the actual package they meant // to uninstall. if (!config.ForceDependencies) { // if you find an install of an .install / .portable / .commandline, allow adding it to the list var installedPackages = get_all_intalled_packages(config).Select(p => p.Name).ToList().@join(ApplicationParameters.PackageNamesSeparator); foreach (var packageName in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null()) { var installerExists = installedPackages.contains("{0}.install".format_with(packageName)); var portableExists = installedPackages.contains("{0}.portable".format_with(packageName)); var cmdLineExists = installedPackages.contains("{0}.commandline".format_with(packageName)); if ((!config.PackageNames.contains("{0}.install".format_with(packageName)) && !config.PackageNames.contains("{0}.portable".format_with(packageName)) && !config.PackageNames.contains("{0}.commandline".format_with(packageName)) ) && (installerExists || portableExists || cmdLineExists) ) { var actualPackageName = installerExists ? "{0}.install".format_with(packageName) : portableExists ? "{0}.portable".format_with(packageName) : "{0}.commandline".format_with(packageName); var timeoutInSeconds = config.PromptForConfirmation ? 0 : 20; this.Log().Warn(@"You are uninstalling {0}, which is likely a metapackage for an *.install/*.portable package that it installed ({0} represents discoverability).".format_with(packageName)); var selection = InteractivePrompt.prompt_for_confirmation( "Would you like to uninstall {0} as well?".format_with(actualPackageName), new[] { "yes", "no" }, defaultChoice: null, requireAnswer: false, allowShortAnswer: true, shortPrompt: true, timeoutInSeconds: timeoutInSeconds ); if (selection.is_equal_to("yes")) { config.PackageNames += ";{0}".format_with(actualPackageName); } else { var logMessage = "To finish removing {0}, please also run the command: `choco uninstall {1}`.".format_with(packageName, actualPackageName); var actualPackageResult = packageUninstalls.GetOrAdd(actualPackageName, new PackageResult(actualPackageName, null, null)); actualPackageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); actualPackageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); } } } } set_package_names_if_all_is_specified(config, () => { // force remove the item, ignore the dependencies // as those are going to be picked up anyway config.Force = true; config.ForceDependencies = false; }); foreach (string packageName in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null()) { IList<IPackage> installedPackageVersions = new List<IPackage>(); if (string.IsNullOrWhiteSpace(config.Version)) { installedPackageVersions = packageManager.LocalRepository.FindPackagesById(packageName).OrderBy((p) => p.Version).ToList(); } else { var semanticVersion = new SemanticVersion(config.Version); installedPackageVersions = packageManager.LocalRepository.FindPackagesById(packageName).Where((p) => p.Version.Equals(semanticVersion)).ToList(); } if (installedPackageVersions.Count == 0) { string logMessage = "{0} is not installed. Cannot uninstall a non-existent package.".format_with(packageName); var missingResult = packageUninstalls.GetOrAdd(packageName, new PackageResult(packageName, null, null)); missingResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); if (config.RegularOutput) this.Log().Error(ChocolateyLoggers.Important, logMessage); continue; } var packageVersionsToRemove = installedPackageVersions.ToList(); if (!config.AllVersions && installedPackageVersions.Count > 1) { if (config.PromptForConfirmation) { packageVersionsToRemove.Clear(); IList<string> choices = new List<string>(); const string abortChoice = "None"; choices.Add(abortChoice); foreach (var installedVersion in installedPackageVersions.or_empty_list_if_null()) { choices.Add(installedVersion.Version.to_string()); } const string allVersionsChoice = "All versions"; if (installedPackageVersions.Count != 1) { choices.Add(allVersionsChoice); } var selection = InteractivePrompt.prompt_for_confirmation("Which version of {0} would you like to uninstall?".format_with(packageName), choices, defaultChoice: null, requireAnswer: true, allowShortAnswer: false); if (string.IsNullOrWhiteSpace(selection)) continue; if (selection.is_equal_to(abortChoice)) continue; if (selection.is_equal_to(allVersionsChoice)) { packageVersionsToRemove = installedPackageVersions.ToList(); if (config.RegularOutput) this.Log().Info(() => "You selected to remove all versions of {0}".format_with(packageName)); } else { IPackage pkg = installedPackageVersions.FirstOrDefault((p) => p.Version.to_string().is_equal_to(selection)); packageVersionsToRemove.Add(pkg); if (config.RegularOutput) this.Log().Info(() => "You selected {0} v{1}".format_with(pkg.Id, pkg.Version.to_string())); } } } foreach (var packageVersion in packageVersionsToRemove) { var pkgInfo = _packageInfoService.get_package_information(packageVersion); if (pkgInfo != null && pkgInfo.IsPinned) { string logMessage = "{0} is pinned. Skipping pinned package.".format_with(packageName); var pinnedResult = packageUninstalls.GetOrAdd(packageName, new PackageResult(packageName, null, null)); pinnedResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); pinnedResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); if (config.RegularOutput) this.Log().Warn(ChocolateyLoggers.Important, logMessage); continue; } if (performAction) { try { using (packageManager.SourceRepository.StartOperation( RepositoryOperationNames.Install, packageVersion.Id, packageVersion.Version.to_string()) ) { if (beforeUninstallAction != null) { // guessing this is not added so that it doesn't fail the action if an error is recorded? //var currentPackageResult = packageUninstalls.GetOrAdd(packageName, new PackageResult(packageVersion, get_install_directory(config, packageVersion))); var currentPackageResult = new PackageResult(packageVersion, get_install_directory(config, packageVersion)); beforeUninstallAction(currentPackageResult); } ensure_package_files_have_compatible_attributes(config, packageVersion, pkgInfo); rename_legacy_package_version(config, packageVersion, pkgInfo); remove_rollback_directory_if_exists(packageName); backup_existing_version(config, packageVersion, pkgInfo); packageManager.UninstallPackage(packageVersion.Id, forceRemove: config.Force, removeDependencies: config.ForceDependencies, version: packageVersion.Version); ensure_nupkg_is_removed(packageVersion, pkgInfo); remove_installation_files(packageVersion, pkgInfo); remove_cache_for_package(config, packageVersion); } } catch (Exception ex) { var logMessage = "{0} not uninstalled. An error occurred during uninstall:{1} {2}".format_with(packageName, Environment.NewLine, ex.Message); this.Log().Error(ChocolateyLoggers.Important, logMessage); var result = packageUninstalls.GetOrAdd(packageVersion.Id.to_lower() + "." + packageVersion.Version.to_string(), new PackageResult(packageVersion, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, packageVersion.Id))); result.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); if (result.ExitCode == 0) result.ExitCode = 1; // do not call continueAction - will result in multiple passes } } else { // continue action won't be found b/c we are not actually uninstalling (this is noop) var result = packageUninstalls.GetOrAdd(packageVersion.Id.to_lower() + "." + packageVersion.Version.to_string(), new PackageResult(packageVersion, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, packageVersion.Id))); if (continueAction != null) continueAction.Invoke(result); } } } return packageUninstalls; }
public bool uninstall(ChocolateyConfiguration configuration, PackageResult packageResult) { return(run_action(configuration, packageResult, CommandNameType.uninstall)); }
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 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)); } }
public ConcurrentDictionary<string, PackageResult> upgrade_run(ChocolateyConfiguration config, Action<PackageResult> continueAction, bool performAction, Action<PackageResult> beforeUpgradeAction = null) { _fileSystem.create_directory_if_not_exists(ApplicationParameters.PackagesLocation); var packageInstalls = new ConcurrentDictionary<string, PackageResult>(StringComparer.InvariantCultureIgnoreCase); SemanticVersion version = config.Version != null ? new SemanticVersion(config.Version) : null; if (config.Force) config.AllowDowngrade = true; var packageManager = NugetCommon.GetPackageManager( config, _nugetLogger, installSuccessAction: (e) => { var pkg = e.Package; var packageResult = packageInstalls.GetOrAdd(pkg.Id.to_lower(), new PackageResult(pkg, e.InstallPath)); packageResult.InstallLocation = e.InstallPath; packageResult.Messages.Add(new ResultMessage(ResultType.Debug, ApplicationParameters.Messages.ContinueChocolateyAction)); if (continueAction != null) continueAction.Invoke(packageResult); }, uninstallSuccessAction: null, addUninstallHandler: false); var configIgnoreDependencies = config.IgnoreDependencies; set_package_names_if_all_is_specified(config, () => { config.IgnoreDependencies = true; }); config.IgnoreDependencies = configIgnoreDependencies; foreach (string packageName in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null()) { remove_rollback_directory_if_exists(packageName); IPackage installedPackage = packageManager.LocalRepository.FindPackage(packageName); if (installedPackage == null) { if (config.UpgradeCommand.FailOnNotInstalled) { string failLogMessage = "{0} is not installed. Cannot upgrade a non-existent package.".format_with(packageName); var result = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, null, null)); result.Messages.Add(new ResultMessage(ResultType.Error, failLogMessage)); if (config.RegularOutput) this.Log().Error(ChocolateyLoggers.Important, failLogMessage); continue; } string logMessage = @"{0} is not installed. Installing...".format_with(packageName); if (config.RegularOutput) this.Log().Warn(ChocolateyLoggers.Important, logMessage); var packageNames = config.PackageNames; config.PackageNames = packageName; if (config.Noop) { install_noop(config, continueAction); } else { var installResults = install_run(config, continueAction); foreach (var result in installResults) { packageInstalls.GetOrAdd(result.Key, result.Value); } } config.PackageNames = packageNames; continue; } if (version != null && version < installedPackage.Version && !config.AllowMultipleVersions && !config.AllowDowngrade) { string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to upgrade to older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); var nullResult = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); continue; } var pkgInfo = _packageInfoService.get_package_information(installedPackage); bool isPinned = pkgInfo != null && pkgInfo.IsPinned; IPackage availablePackage = packageManager.SourceRepository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false); if (availablePackage == null) { string logMessage = "{0} was not found with the source(s) listed.{1} If you specified a particular version and are receiving this message, it is possible that the package name exists but the version does not.{1} Version: \"{2}\"{1} Source(s): \"{3}\"".format_with(packageName, Environment.NewLine, config.Version, config.Sources); var unfoundResult = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, version.to_string(), null)); if (config.UpgradeCommand.FailOnUnfound) { unfoundResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); if (config.RegularOutput) this.Log().Error(ChocolateyLoggers.Important, logMessage); } else { unfoundResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); unfoundResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); if (config.RegularOutput) { this.Log().Warn(ChocolateyLoggers.Important, logMessage); } else { //last one is whether this package is pinned or not this.Log().Info("{0}|{1}|{1}|{2}".format_with(installedPackage.Id, installedPackage.Version, isPinned.to_string().to_lower())); } } continue; } if (pkgInfo != null && pkgInfo.IsSideBySide) { //todo: get smarter about realizing multiple versions have been installed before and allowing that } var packageResult = packageInstalls.GetOrAdd(packageName, new PackageResult(availablePackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, availablePackage.Id))); if (installedPackage.Version > availablePackage.Version && !config.AllowDowngrade) { string logMessage = "{0} v{1} is newer than the most recent.{2} You must be smarter than the average bear...".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); if (!config.UpgradeCommand.NotifyOnlyAvailableUpgrades) { if (config.RegularOutput) { this.Log().Info(ChocolateyLoggers.Important, logMessage); } else { this.Log().Info("{0}|{1}|{1}|{2}".format_with(installedPackage.Id, installedPackage.Version, isPinned.to_string().to_lower())); } } continue; } if (installedPackage.Version == availablePackage.Version) { string logMessage = "{0} v{1} is the latest version available based on your source(s).".format_with(installedPackage.Id, installedPackage.Version); if (!config.Force) { if (packageResult.Messages.Count((p) => p.Message == ApplicationParameters.Messages.ContinueChocolateyAction) == 0) { packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); } if (!config.UpgradeCommand.NotifyOnlyAvailableUpgrades) { if (config.RegularOutput) { this.Log().Info(logMessage); } else { this.Log().Info("{0}|{1}|{2}|{3}".format_with(installedPackage.Id, installedPackage.Version, availablePackage.Version, isPinned.to_string().to_lower())); } } continue; } packageResult.Messages.Add(new ResultMessage(ResultType.Note, logMessage)); if (config.RegularOutput) this.Log().Info(logMessage); } if ((availablePackage.Version > installedPackage.Version) || config.Force || (availablePackage.Version < installedPackage.Version && config.AllowDowngrade)) { if (availablePackage.Version > installedPackage.Version) { string logMessage = "You have {0} v{1} installed. Version {2} is available based on your source(s).".format_with(installedPackage.Id, installedPackage.Version, availablePackage.Version); packageResult.Messages.Add(new ResultMessage(ResultType.Note, logMessage)); if (config.RegularOutput) { this.Log().Warn(logMessage); } else { this.Log().Info("{0}|{1}|{2}|{3}".format_with(installedPackage.Id, installedPackage.Version, availablePackage.Version, isPinned.to_string().to_lower())); } } if (isPinned) { string logMessage = "{0} is pinned. Skipping pinned package.".format_with(packageName); packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); if (config.RegularOutput) this.Log().Warn(ChocolateyLoggers.Important, logMessage); continue; } if (performAction) { try { using (packageManager.SourceRepository.StartOperation( RepositoryOperationNames.Update, packageName, version == null ? null : version.ToString())) { ensure_package_files_have_compatible_attributes(config, installedPackage, pkgInfo); rename_legacy_package_version(config, installedPackage, pkgInfo); if (beforeUpgradeAction != null) { var currentPackageResult = new PackageResult(installedPackage, get_install_directory(config, installedPackage)); beforeUpgradeAction(currentPackageResult); } backup_existing_version(config, installedPackage, pkgInfo); remove_shim_directors(config, installedPackage, pkgInfo); if (config.Force && (installedPackage.Version == availablePackage.Version)) { FaultTolerance.try_catch_with_logging_exception( () => { _fileSystem.delete_directory_if_exists(_fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id), recursive: true); remove_cache_for_package(config, installedPackage); }, "Error during force upgrade"); packageManager.InstallPackage(availablePackage, config.IgnoreDependencies, config.Prerelease); } else { packageManager.UpdatePackage(availablePackage, updateDependencies: !config.IgnoreDependencies, allowPrereleaseVersions: config.Prerelease); } remove_nuget_cache_for_package(availablePackage); } } catch (Exception ex) { var logMessage = "{0} not upgraded. An error occurred during installation:{1} {2}".format_with(packageName, Environment.NewLine, ex.Message); this.Log().Error(ChocolateyLoggers.Important, logMessage); packageResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); if (continueAction != null) continueAction.Invoke(packageResult); } } } } return packageInstalls; }
public void install(ChocolateyConfiguration configuration, PackageResult packageResult) { _fileSystem.create_directory_if_not_exists(ApplicationParameters.ShimsLocation); if (packageResult.InstallLocation.is_equal_to(ApplicationParameters.InstallLocation) || packageResult.InstallLocation.is_equal_to(ApplicationParameters.PackagesLocation)) { var logMessage = "Install location is not specific enough, cannot run shimgen:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation); packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); this.Log().Error(logMessage.escape_curly_braces()); return; } //gather all .exes in the folder var exeFiles = _fileSystem.get_files(packageResult.InstallLocation, pattern: "*.exe", option: SearchOption.AllDirectories); foreach (string file in exeFiles.or_empty_list_if_null()) { if (_fileSystem.file_exists(file + ".ignore")) { continue; } bool isGui = _fileSystem.file_exists(file + ".gui"); //todo: v2 be able to determine gui automatically var args = ExternalCommandArgsBuilder.build_arguments(configuration, _shimGenArguments); var shimLocation = _fileSystem.combine_paths(ApplicationParameters.ShimsLocation, _fileSystem.get_file_name(file)); var argsForPackage = args.Replace(PATH_TOKEN, file.Replace(ApplicationParameters.InstallLocation, "..\\")).Replace(OUTPUT_TOKEN, shimLocation).Replace(ICON_PATH_TOKEN, file); if (isGui) { argsForPackage += " --gui"; } var exitCode = _commandExecutor.execute( _shimGenExePath, argsForPackage, configuration.CommandExecutionTimeoutSeconds, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Debug(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces())); }, (s, e) => { if (string.IsNullOrWhiteSpace(e.Data)) { return; } this.Log().Error(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces())); }, updateProcessPath: true ); if (exitCode != 0) { Environment.ExitCode = exitCode; } else { this.Log().Info(() => " ShimGen has successfully created a {0}shim for {1}".format_with(isGui ? "gui " : string.Empty, _fileSystem.get_file_name(file))); this.Log().Debug(() => " Created: {0}{1} Targeting: {2}{1} IsGui:{3}{1}".format_with(shimLocation, Environment.NewLine, file, isGui)); } } }
public void uninstall(ChocolateyConfiguration configuration, PackageResult packageResult) { //gather all .exes in the folder var exeFiles = _fileSystem.get_files(packageResult.InstallLocation, pattern: "*.exe", option: SearchOption.AllDirectories); foreach (string file in exeFiles.or_empty_list_if_null()) { if (_fileSystem.file_exists(file + ".ignore")) continue; var shimLocation = _fileSystem.combine_paths(ApplicationParameters.ShimsLocation, _fileSystem.get_file_name(file)); this.Log().Debug(() => "Removing shim for {0} at '{1}".format_with(_fileSystem.get_file_name(file), shimLocation)); _fileSystem.delete_file(shimLocation); } }
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 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 bool before_modify(ChocolateyConfiguration configuration, PackageResult packageResult) { return run_action(configuration, packageResult, CommandNameType.upgrade); }
private void SavePlan() { if (!Page.IsValid) { return; } // gather form info HostingPlanInfo plan = new HostingPlanInfo(); plan.UserId = PanelSecurity.SelectedUserId; plan.PlanId = PanelRequest.PlanID; plan.IsAddon = false; plan.PlanName = Server.HtmlEncode(txtPlanName.Text); plan.PlanDescription = Server.HtmlEncode(txtPlanDescription.Text); plan.Available = true; // always available plan.SetupPrice = 0; plan.RecurringPrice = 0; plan.RecurrenceLength = 1; plan.RecurrenceUnit = 2; // month plan.PackageId = Utils.ParseInt(ddlSpace.SelectedValue, 0); plan.ServerId = Utils.ParseInt(ddlServer.SelectedValue, 0); // if this is non-admin // get server info from parent package if (PanelSecurity.EffectiveUser.Role != UserRole.Administrator) { try { PackageInfo package = ES.Services.Packages.GetPackage(plan.PackageId); if (package != null) { plan.ServerId = package.ServerId; } } catch (Exception ex) { ShowErrorMessage("PACKAGE_GET_PACKAGE", ex); return; } } plan.Groups = hostingPlansQuotas.Groups; plan.Quotas = hostingPlansQuotas.Quotas; int planId = PanelRequest.PlanID; if ((PanelRequest.PlanID == 0) || ShouldCopyCurrentHostingPlan()) { // new plan try { planId = ES.Services.Packages.AddHostingPlan(plan); if (planId < 0) { ShowResultMessage(planId); return; } } catch (Exception ex) { ShowErrorMessage("PLAN_ADD_PLAN", ex); return; } } else { // update plan try { PackageResult result = ES.Services.Packages.UpdateHostingPlan(plan); if (result.Result < 0) { ShowResultMessage(result.Result); lblMessage.Text = AntiXss.HtmlEncode(GetExceedingQuotasMessage(result.ExceedingQuotas)); return; } } catch (Exception ex) { ShowErrorMessage("PLAN_UPDATE_PLAN", ex); return; } } // redirect RedirectBack(); }
private void CreateHostingSpace() { if (!Page.IsValid) return; string spaceName = ddlPlans.SelectedItem.Text; string ftpAccount = (rbFtpAccountName.SelectedIndex == 0) ? null : ftpAccountName.Text; string domainName = txtDomainName.Text.Trim(); PackageResult result = null; try { result = ES.Services.Packages.AddPackageWithResources(PanelSecurity.SelectedUserId, Utils.ParseInt(ddlPlans.SelectedValue, 0), spaceName, Utils.ParseInt(ddlStatus.SelectedValue, 0), chkPackageLetter.Checked, chkCreateResources.Checked, domainName, false, chkCreateWebSite.Checked, chkCreateFtpAccount.Checked, ftpAccount, chkCreateMailAccount.Checked, txtHostName.Text); if (result.Result < 0) { ShowResultMessage(result.Result); lblMessage.Text = PortalAntiXSS.Encode(GetExceedingQuotasMessage(result.ExceedingQuotas)); return; } else { if ((chkIntegratedOUProvisioning.Checked) & !string.IsNullOrEmpty(domainName)) { UserInfo user = UsersHelper.GetUser(PanelSecurity.SelectedUserId); if (user != null) { if (user.Role != UserRole.Reseller) { UserSettings settings = ES.Services.Users.GetUserSettings(user.UserId, UserSettings.EXCHANGE_POLICY); string orgId = domainName.ToLower(); if (settings != null && settings["OrgIdPolicy"] != null) { orgId = GetOrgId(settings["OrgIdPolicy"], domainName, result.Result); } ES.Services.Organizations.CreateOrganization(result.Result, orgId, domainName.ToLower(), domainName.ToLower()); if (result.Result < 0) { ShowErrorMessage("USERWIZARD_CREATE_ACCOUNT"); return; } } } } } } catch (Exception ex) { ShowErrorMessage("USERWIZARD_CREATE_ACCOUNT", ex); return; } // Save addons try { int spaceId = result.Result; foreach (RepeaterItem item in repHostingAddons.Items) { PackageAddonInfo addon = new PackageAddonInfo(); addon.PackageAddonId = 0; //PanelRequest.PackageAddonID; addon.PackageId = spaceId; //PanelSecurity.PackageId; addon.Comments = ""; addon.PlanId = Utils.ParseInt(GetDropDownListSelectedValue(item, "ddlPlan"), 0); addon.StatusId = Utils.ParseInt(ddlStatus.SelectedValue, 0); addon.PurchaseDate = DateTime.Now; addon.Quantity = Utils.ParseInt(GetTextBoxText(item, "txtQuantity"), 1); PackageResult addonResult = ES.Services.Packages.AddPackageAddon(addon); } if (rbPackageQuotas.Checked) { //TODO: add logic to recalculate quota //If checked rbPackageQuotas take all addons quota, sum it and replace to main hosting quota //You can look the idea from SpaceEditDetails, but in SpaceEditDetails it is manually, need automatic here //At this moment here is a lot of work, maybe later. } //PackageContext cntx = PackagesHelper.GetCachedPackageContext(spaceId); //string resourceGroup = "VPS2012"; //if (cntx != null && cntx.Groups.ContainsKey(resourceGroup)) //{ // string pageId = "SpaceVPS2012"; // string pageUrl = PortalUtils.NavigatePageURL( //pageId, PortalUtils.SPACE_ID_PARAM, spaceId.ToString(), null); // Response.Redirect(pageUrl); //} } catch { //If something happens here, just ignore it. Addons not so important that a Hosting Space } if (chkRedirectToCreateVPS.Checked) { string pageId = "SpaceVPS2012"; string pageUrl = PortalUtils.NavigatePageURL( pageId, PortalUtils.SPACE_ID_PARAM, result.Result.ToString(), null); Response.Redirect(pageUrl); } else { // go to space home Response.Redirect(PortalUtils.GetSpaceHomePageUrl(result.Result)); } }
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("installerArguments", configuration.InstallArguments); Environment.SetEnvironmentVariable("chocolateyInstallArguments", configuration.InstallArguments); Environment.SetEnvironmentVariable("chocolateyPackageParameters", configuration.PackageParameters); if (configuration.ForceX86) { Environment.SetEnvironmentVariable("chocolateyForceX86", "true"); } if (configuration.OverrideArguments) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); } 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? NOTE: If you choose not to run the script, the installation will fail. Skip is an advanced option and most likely will never be wanted. " , new[] { "yes", "no", "skip" }, "no", 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), _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 override void Context() { base.Context(); packageResult = new PackageResult("bob", "1.2.3", ApplicationParameters.PackagesLocation); }
private void SaveSpace() { if (!Page.IsValid) { return; } // gather form data PackageInfo package = new PackageInfo(); // load package for update if (PanelSecurity.PackageId > 0) { package = ES.Services.Packages.GetPackage(PanelSecurity.PackageId); } package.PackageId = PanelSecurity.PackageId; package.PackageName = txtName.Text; package.PackageComments = txtComments.Text; package.PlanId = Utils.ParseInt(ddlPlan.SelectedValue, 0); package.PurchaseDate = PurchaseDate.SelectedDate; package.OverrideQuotas = rbPackageQuotas.Checked; if (package.OverrideQuotas) { package.Groups = editPackageQuotas.Groups; package.Quotas = editPackageQuotas.Quotas; } try { // update existing package PackageResult result = ES.Services.Packages.UpdatePackage(package); if (result.Result < 0) { ShowResultMessage(result.Result); lblMessage.Text = PortalAntiXSS.Encode(GetExceedingQuotasMessage(result.ExceedingQuotas)); return; } bool notUserRoleAndNotSelectedTheSameUser = (PanelSecurity.SelectedUserId != Convert.ToInt32(ddlUser.SelectedValue) && PanelSecurity.LoggedUser.Role != UserRole.User); if (chkMoveUser.Checked && notUserRoleAndNotSelectedTheSameUser) { int changeResult = ES.Services.Packages.ChangePackageUser(PanelSecurity.PackageId, Convert.ToInt32(ddlUser.SelectedValue)); if (changeResult < 0) { ShowResultMessage(result.Result); return; } } } catch (Exception ex) { ShowErrorMessage("PACKAGE_UPDATE_PACKAGE", ex); return; } // return RedirectSpaceHomePage(); }
public bool install(ChocolateyConfiguration configuration, PackageResult packageResult) { return run_action(configuration, packageResult, CommandNameType.install); }
public override void Context() { base.Context(); packageResult = null; }
public void run(PackageResult packageResult, ChocolateyConfiguration config) { if (!config.Features.AutoUninstaller) { this.Log().Info(" Skipping auto uninstaller - AutoUninstaller feature is not enabled."); return; } var pkgInfo = _packageInfoService.get_package_information(packageResult.Package); if (pkgInfo.RegistrySnapshot == null) { this.Log().Info(" Skipping auto uninstaller - No registry snapshot."); return; } var registryKeys = pkgInfo.RegistrySnapshot.RegistryKeys; if (registryKeys == null || registryKeys.Count == 0) { this.Log().Info(" Skipping auto uninstaller - No registry keys in snapshot."); return; } this.Log().Info(" Running auto uninstaller..."); if (WaitForCleanup) { this.Log().Debug("Sleeping for {0} seconds to allow Windows to finish cleaning up.".format_with(SLEEP_TIME)); Thread.Sleep((int)TimeSpan.FromSeconds(SLEEP_TIME).TotalMilliseconds); } foreach (var key in registryKeys.or_empty_list_if_null()) { this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString.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 - The application appears to have been uninstalled already by other means."); 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))); continue; } // 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(); var uninstallArgs = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty); uninstallExe = uninstallExe.remove_surrounding_quotes(); this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe)); IInstaller installer = new CustomInstaller(); switch (key.InstallerType) { case InstallerType.Msi: installer = new MsiInstaller(); break; case InstallerType.InnoSetup: installer = new InnoSetupInstaller(); break; case InstallerType.Nsis: installer = new NsisInstaller(); break; case InstallerType.InstallShield: installer = new InstallShieldInstaller(); break; } 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(); } var packageCacheLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), pkgInfo.Package.Id, pkgInfo.Package.Version.to_string()); 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)) { 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)); } } }
public HandlePackageResultCompletedMessage(PackageResult packageResult, ChocolateyConfiguration config, CommandNameType commandName) { PackageResult = packageResult; Config = config; CommandName = commandName; }