Skip to content

Commit

Permalink
(chocolateyGH-1133) Autouninstaller - Use Uninstall Args / Override
Browse files Browse the repository at this point in the history
If a user provides uninstall arguments and optionally to override the
original arguments, then those should be used with AutoUninstaller as
well. Previously, auto uninstaller would calculate its own and ignore
any input from the user. With this change, it will use those arguments
that are provided.
  • Loading branch information
ferventcoder committed Aug 29, 2017
1 parent e480224 commit fb8c377
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public override void Context()
service.WaitForCleanup = false;
config.Features.AutoUninstaller = true;
config.PromptForConfirmation = false;
config.PackageNames = "regular";
package.Setup(p => p.Id).Returns("regular");
package.Setup(p => p.Version).Returns(new SemanticVersion("1.2.0"));
packageResult = new PackageResult(package.Object, "c:\\packages\\thispackage");
Expand Down Expand Up @@ -471,7 +472,7 @@ public void should_call_command_executor()
Times.Once);
}
}

public class when_uninstall_string_is_split_by_quotes : AutomaticUninstallerServiceSpecsBase
{
private readonly string uninstallStringWithQuoteSeparation = @"""C:\Program Files (x86)\WinDirStat\Uninstall.exe"" ""WinDir Stat""";
Expand Down Expand Up @@ -612,6 +613,111 @@ public void should_not_call_command_executor()
}
}

public class when_AutomaticUninstallerService_is_passed_uninstall_arguments_from_command_line : AutomaticUninstallerServiceSpecsBase
{
IInstaller _installerType = new InnoSetupInstaller();

public override void Context()
{
base.Context();
registryKeys.Clear();
registryKeys.Add(
new RegistryApplicationKey
{
DisplayName = expectedDisplayName,
InstallLocation = @"C:\Program Files (x86)\WinDirStat",
UninstallString = originalUninstallString,
HasQuietUninstall = false,
KeyPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinDirStat",
InstallerType = _installerType.InstallerType,
});
packageInformation.RegistrySnapshot = new Registry("123", registryKeys);

config.InstallArguments = "/bob /nope";
}

public override void Because()
{
service.run(packageResult, config);
}

[Fact]
public void should_call_get_package_information()
{
packageInfoService.Verify(s => s.get_package_information(It.IsAny<IPackage>()), Times.Once);
}

[Fact]
public void should_call_command_executor_appending_passed_arguments()
{
var uninstallArgs = _installerType.build_uninstall_command_arguments().trim_safe();

uninstallArgs += " {0}".format_with(config.InstallArguments);

commandExecutor.Verify(
c =>
c.execute(
expectedUninstallString,
uninstallArgs,
It.IsAny<int>(),
It.IsAny<Action<object, DataReceivedEventArgs>>(),
It.IsAny<Action<object, DataReceivedEventArgs>>(),
It.IsAny<bool>()),
Times.Once);
}
}

public class when_AutomaticUninstallerService_is_passed_overriding_uninstall_arguments_from_command_line : AutomaticUninstallerServiceSpecsBase
{
IInstaller _installerType = new InnoSetupInstaller();

public override void Context()
{
base.Context();
registryKeys.Clear();
registryKeys.Add(
new RegistryApplicationKey
{
DisplayName = expectedDisplayName,
InstallLocation = @"C:\Program Files (x86)\WinDirStat",
UninstallString = originalUninstallString,
HasQuietUninstall = false,
KeyPath = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinDirStat",
InstallerType = _installerType.InstallerType,
});
packageInformation.RegistrySnapshot = new Registry("123", registryKeys);

config.InstallArguments = "/bob /nope";
config.OverrideArguments = true;
}

public override void Because()
{
service.run(packageResult, config);
}

[Fact]
public void should_call_get_package_information()
{
packageInfoService.Verify(s => s.get_package_information(It.IsAny<IPackage>()), Times.Once);
}

[Fact]
public void should_call_command_executor_with_only_passed_arguments()
{
commandExecutor.Verify(
c =>
c.execute(
expectedUninstallString,
config.InstallArguments,
It.IsAny<int>(),
It.IsAny<Action<object, DataReceivedEventArgs>>(),
It.IsAny<Action<object, DataReceivedEventArgs>>(),
It.IsAny<bool>()),
Times.Once);
}
}

public class when_AutomaticUninstallerService_defines_uninstall_switches : AutomaticUninstallerServiceSpecsBase
{
private Action because;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace chocolatey.infrastructure.app.services
using infrastructure.commands;
using logging;
using results;
using utility;

public class AutomaticUninstallerService : IAutomaticUninstallerService
{
Expand Down Expand Up @@ -97,16 +98,30 @@ public void run(PackageResult packageResult, ChocolateyConfiguration config)
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())
{
var packageCacheLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), pkgInfo.Package.Id, pkgInfo.Package.Version.to_string());
var packageCacheLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), package.Id, package.Version.to_string());
remove(key, config, packageResult, packageCacheLocation);
}
}

public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, PackageResult packageResult, string packageCacheLocation)
{
var userProvidedUninstallArguments = string.Empty;
var userOverrideUninstallArguments = false;
var package = packageResult.Package;
if (package != null)
{
if (!PackageUtility.package_is_a_dependency(config, package.Id) || config.ApplyInstallArgumentsToDependencies)
{
userProvidedUninstallArguments = config.InstallArguments;
userOverrideUninstallArguments = config.OverrideArguments;

if (!string.IsNullOrWhiteSpace(userProvidedUninstallArguments)) this.Log().Debug(ChocolateyLoggers.Verbose, " Using user passed {2}uninstaller args for {0}:'{1}'".format_with(package.Id, userProvidedUninstallArguments.escape_curly_braces(), userOverrideUninstallArguments ? "overriding " : string.Empty));
}
}

//todo: if there is a local package, look to use it in the future
if (string.IsNullOrWhiteSpace(key.UninstallString))
{
Expand Down Expand Up @@ -145,6 +160,7 @@ public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, P
}
}
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));

Expand Down Expand Up @@ -175,6 +191,20 @@ public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, P
uninstallArgs += " " + installer.build_uninstall_command_arguments();
}

if (!string.IsNullOrWhiteSpace(userProvidedUninstallArguments))
{
if (userOverrideUninstallArguments)
{
this.Log().Debug(() => " Replacing original uninstall arguments of '{0}' with '{1}'".format_with(uninstallArgs.escape_curly_braces(),userProvidedUninstallArguments.escape_curly_braces()));
uninstallArgs = userProvidedUninstallArguments;
}
else
{
this.Log().Debug(() => " Appending original uninstall arguments with '{0}'".format_with(userProvidedUninstallArguments.escape_curly_braces()));
uninstallArgs += " " + userProvidedUninstallArguments;
}
}

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);
Expand Down

0 comments on commit fb8c377

Please sign in to comment.