Refactored default package removal function based on registry key UninstallString.

This commit is contained in:
László Valkó 2018-05-12 05:53:42 +02:00
parent a02bcc628b
commit 367a21eaab

View file

@ -1543,14 +1543,61 @@ sub run_exe ($$$$$$$;$)
return (undef, undef); return (undef, undef);
} }
sub remove_package_fallback ($$$$$$$$$$$)
{
my ($channel, $vars, $paramlist, $inst, $condition, $dispname, $ver, $printver, $db, $counters, $removecontext) = @_;
print_log($channel, DEBUG1, 'Removing package %s%s%s', $dispname, $printver,
defined $condition ? ' with true condition' : '');
my $uninst = $$inst{Uninstall};
my $quninst = $$inst{QUninstall};
return sprintf('Cannot remove package %s%s, no remove steps defined and no UninstallString registry entry found',
$dispname, $ver) unless defined $uninst || defined $quninst;
$uninst = $quninst if defined $quninst;
$uninst =~ s/(msiexec[^ ]* )\/i/$1\/X/io;
$uninst =~ s/(msiexec[^ ]* )/$1\/qb \/norestart \/passive /io;
print_log($channel, DEBUG2, 'Uninstall command: %s', $uninst);
if (! defined $$removecontext{exename}) {
$$removecontext{exename} = substitute_variables($vars, '%systemroot%/System32/cmd.exe', 1, undef, $channel);
my $params = '';
if (defined $paramlist && scalar @$paramlist > 0) {
foreach my $param (@$paramlist) {
$param = substitute_variables($vars, $param, 0, undef, $channel)
if $param =~ /%[^%]*%/o;
$params .= ' '.$param;
}
}
$params = ' '.$params unless $params eq '';
$$removecontext{params} = $params;
}
$uninst .= $$removecontext{params};
my ($error, $exitcode) = run_exe($channel, $db, $vars, undef, $$removecontext{exename}, ['/C', $uninst], 0);
if (defined $error) {
if (defined $exitcode && $exitcode == 194) {
print_log($channel, INFO, 'Ignoring package %s%s removal exit code: %s',
$dispname, $printver, $exitcode);
$$counters{RebootFlag} = 1;
}
else {
push @{$$counters{FailList}}, $dispname;
$$counters{FailCount}++;
return $error;
}
}
push @{$$counters{RemovedList}}, $dispname;
$$counters{RemovedCount}++;
return undef;
}
sub remove_packages ($$$$$$$$$$) sub remove_packages ($$$$$$$$$$)
{ {
my ($channel, $vars, $def, $paramlist, $list, $condition, $db, $basedir, $config, $counters) = @_; my ($channel, $vars, $def, $paramlist, $list, $condition, $db, $basedir, $config, $counters) = @_;
my $params; my $removecontext = {};
my $exename;
$list = sort_packages_to_remove($list); $list = sort_packages_to_remove($list);
foreach my $inst (@$list) { foreach my $inst (@$list) {
my $dispname = $$inst{DisplayName};
my $ver = extract_package_version($channel, $def, $inst, $basedir, $config); my $ver = extract_package_version($channel, $def, $inst, $basedir, $config);
$ver = $$inst{DisplayVersion} unless defined $ver; $ver = $$inst{DisplayVersion} unless defined $ver;
my $printver = defined $ver ? ' ('.$ver.')' : ''; my $printver = defined $ver ? ' ('.$ver.')' : '';
@ -1561,56 +1608,18 @@ sub remove_packages ($$$$$$$$$$)
my ($result, $error) = check_condition($channel, $vars, $condition); my ($result, $error) = check_condition($channel, $vars, $condition);
if (! defined $result) { if (! defined $result) {
print_log($channel, INFO, 'Ignoring package %s%s: %s', print_log($channel, INFO, 'Ignoring package %s%s: %s',
$$inst{DisplayName}, $printver, $error); $dispname, $printver, $error);
next; next;
} }
if (! $result) { if (! $result) {
print_log($channel, INFO, 'Ignoring package %s%s with false condition', print_log($channel, INFO, 'Ignoring package %s%s with false condition',
$$inst{DisplayName}, $printver); $dispname, $printver);
next; next;
} }
} }
my $error = remove_package_fallback($channel, $vars, $paramlist, $inst, $condition, $dispname,
print_log($channel, DEBUG1, 'Removing package %s%s%s', $$inst{DisplayName}, $printver, $ver, $printver, $db, $counters, $removecontext);
defined $condition ? ' with true condition' : ''); return $error if defined $error;
my $uninst = $$inst{Uninstall};
my $quninst = $$inst{QUninstall};
return sprintf('Cannot remove package %s%s, no UninstallString registry entry found',
$$inst{DisplayName}, $ver) unless defined $uninst || defined $quninst;
$uninst = $quninst if defined $quninst;
$uninst =~ s/(msiexec[^ ]* )\/i/$1\/X/io;
$uninst =~ s/(msiexec[^ ]* )/$1\/qb \/norestart \/passive /io;
print_log($channel, DEBUG2, 'Uninstall command: %s', $uninst);
$exename = substitute_variables($vars, '%systemroot%/System32/cmd.exe', 1, undef, 'pkg')
unless defined $exename;
if (! defined $params) {
$params = '';
if (defined $paramlist && scalar @$paramlist > 0) {
foreach my $param (@$paramlist) {
$param = substitute_variables($vars, $param, 0, undef, $channel)
if $param =~ /%[^%]*%/o;
$params .= ' '.$param;
}
}
$params = ' '.$params unless $params eq '';
}
$uninst .= $params;
my ($error, $exitcode) = run_exe($channel, $db, $vars, undef, $exename, ['/C', $uninst], 0);
if (defined $error) {
if (defined $exitcode && $exitcode == 194) {
print_log($channel, INFO, 'Ignoring package %s%s removal exit code: %s',
$$inst{DisplayName}, $printver, $exitcode);
$$counters{RebootFlag} = 1;
}
else {
push @{$$counters{FailList}}, $$inst{DisplayName};
$$counters{FailCount}++;
return $error;
}
}
push @{$$counters{RemovedList}}, $$inst{DisplayName};
$$counters{RemovedCount}++;
} }
return undef; return undef;
} }