From c8d9630c8698f9738b423198d9119d1aac8b2aed Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Thu, 4 Jun 2015 12:32:46 -0500 Subject: [PATCH 1/2] (maint) formatting --- .../infrastructure.app/domain/InstallShieldInstaller.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs b/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs index f8be43d96d..99eda0b30f 100644 --- a/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs +++ b/src/chocolatey/infrastructure.app/domain/InstallShieldInstaller.cs @@ -15,9 +15,7 @@ namespace chocolatey.infrastructure.app.domain { - using System; using System.Collections.Generic; - using System.Text; /// /// InstallShield Installer Options @@ -40,8 +38,8 @@ public InstallShieldInstaller() SilentUninstall = "/uninst /s"; OtherUninstallOptions = "/sms"; // http://helpnet.installshield.com/installshield18helplib/IHelpSetup_EXEErrors.htm - ValidInstallExitCodes = new List { 0, 1641, 3010 }; - ValidUninstallExitCodes = new List { 0, 1641, 3010 }; + ValidInstallExitCodes = new List {0, 1641, 3010}; + ValidUninstallExitCodes = new List {0, 1641, 3010}; } public override InstallerType InstallerType From b5bef7cf6b72308b218f4d5ab5f2930d06a789e7 Mon Sep 17 00:00:00 2001 From: Rob Reynolds Date: Thu, 4 Jun 2015 13:05:26 -0500 Subject: [PATCH 2/2] (GH-305) Uninstaller confirm when not silent When not silent, the uninstaller should confirm with the user or skip the attempt if confirm is already selected. --- .../AutomaticUninstallerServiceSpecs.cs | 57 ++++++++++++++++--- .../services/AutomaticUninstallerService.cs | 17 ++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/chocolatey.tests/infrastructure.app/services/AutomaticUninstallerServiceSpecs.cs b/src/chocolatey.tests/infrastructure.app/services/AutomaticUninstallerServiceSpecs.cs index 8b9facb3a7..fe31ce0895 100644 --- a/src/chocolatey.tests/infrastructure.app/services/AutomaticUninstallerServiceSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/services/AutomaticUninstallerServiceSpecs.cs @@ -60,6 +60,7 @@ public override void Context() service = new AutomaticUninstallerService(packageInfoService.Object, fileSystem.Object, registryService.Object, commandExecutor.Object); service.WaitForCleanup = false; config.Features.AutoUninstaller = true; + config.PromptForConfirmation = false; package.Setup(p => p.Id).Returns("regular"); package.Setup(p => p.Version).Returns(new SemanticVersion("1.2.0")); packageResult = new PackageResult(package.Object, null); @@ -68,8 +69,9 @@ public override void Context() { InstallLocation = @"C:\Program Files (x86)\WinDirStat", UninstallString = originalUninstallString, - HasQuietUninstall = false, + HasQuietUninstall = true, KeyPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinDirStat", + InstallerType = installerType.InstallerType, }); packageInformation.RegistrySnapshot = new Registry("123", registryKeys); packageInfoService.Setup(s => s.get_package_information(package.Object)).Returns(packageInformation); @@ -203,7 +205,7 @@ public override void Context() { InstallLocation = string.Empty, UninstallString = originalUninstallString, - HasQuietUninstall = false, + HasQuietUninstall = true, KeyPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinDirStat" }); packageInformation.RegistrySnapshot = new Registry("123", registryKeys); @@ -303,6 +305,47 @@ public void should_call_command_executor() commandExecutor.Verify(c => c.execute(expectedUninstallString, installerType.build_uninstall_command_arguments().trim_safe(), It.IsAny(), It.IsAny>(), It.IsAny>(), It.IsAny()), Times.Once); } } + + public class when_AutomaticUninstallerService_cannot_determine_silent_install_arguments : AutomaticUninstallerServiceSpecsBase + { + + public override void Context() + { + base.Context(); + registryKeys.Clear(); + commandExecutor.ResetCalls(); + registryKeys.Add(new RegistryApplicationKey + { + InstallLocation = @"C:\Program Files (x86)\WinDirStat", + UninstallString = "{0} {1}".format_with(originalUninstallString, "/bob"), + HasQuietUninstall = false, + KeyPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinDirStat", + InstallerType = InstallerType.Unknown, + }); + packageInformation.RegistrySnapshot = new Registry("123", registryKeys); + fileSystem.Setup(x => x.combine_paths(config.CacheLocation, It.IsAny(), It.IsAny())).Returns(""); + + } + + // under normal circumstances, it prompts so the user can decide, but if -y is passed it will skip + + public override void Because() + { + service.run(packageResult, config); + } + + [Fact] + public void should_log_why_it_skips_auto_uninstaller() + { + MockLogger.Verify(l => l.Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists."), Times.Once); + } + + [Fact] + public void should_not_call_command_executor() + { + commandExecutor.Verify(c => c.execute(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny>(), It.IsAny()), Times.Never); + } + } public class when_AutomaticUninstallerService_defines_uninstall_switches : AutomaticUninstallerServiceSpecsBase { @@ -345,11 +388,11 @@ private void test_installertype(IInstaller installer, bool hasQuietUninstallStri commandExecutor.Verify(c => c.execute(expectedUninstallString, uninstallArgs.trim_safe(), It.IsAny(), It.IsAny>(), It.IsAny>(), It.IsAny()), Times.Once); } - [Fact] - public void should_use_CustomInstaller_uninstall_args_when_installtype_is_unknown_and_has_quiet_uninstall_is_false() - { - test_installertype(new CustomInstaller(), hasQuietUninstallString: false); - } + //[Fact] + //public void should_use_CustomInstaller_uninstall_args_when_installtype_is_unknown_and_has_quiet_uninstall_is_false() + //{ + // test_installertype(new CustomInstaller(), hasQuietUninstallString: false); + //} [Fact] public void should_use_registry_uninstall_args_when_installtype_is_unknown_and_has_quiet_uninstall_is_true() diff --git a/src/chocolatey/infrastructure.app/services/AutomaticUninstallerService.cs b/src/chocolatey/infrastructure.app/services/AutomaticUninstallerService.cs index 41ceb166e3..7c441ee404 100644 --- a/src/chocolatey/infrastructure.app/services/AutomaticUninstallerService.cs +++ b/src/chocolatey/infrastructure.app/services/AutomaticUninstallerService.cs @@ -19,6 +19,7 @@ namespace chocolatey.infrastructure.app.services using System.Collections.Generic; using System.Linq; using System.Threading; + using commandline; using configuration; using domain; using filesystem; @@ -133,6 +134,22 @@ public void run(PackageResult packageResult, ChocolateyConfiguration config) this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs)); + 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); + if (selection.is_equal_to("no")) skipUninstaller = false; + } + + if (skipUninstaller) + { + this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists."); + return; + } + } + var exitCode = _commandExecutor.execute( uninstallExe, uninstallArgs.trim_safe(),