private static ActionResult DoUninstall(PluginInstaller pluginInstaller, ActionExecuter action, PackageDef package, bool force, string target) { var result = ActionResult.Ok; var destination = package.IsSystemWide() ? PackageDef.SystemWideInstallationDirectory : target; var filesToRemain = new Installation(destination).GetPackages().Where(p => p.Name != package.Name).SelectMany(p => p.Files).Select(f => f.RelativeDestinationPath).Distinct(StringComparer.InvariantCultureIgnoreCase).ToHashSet(StringComparer.InvariantCultureIgnoreCase); try { CustomPackageActionHelper.RunCustomActions(package, PackageActionStage.Uninstall, new CustomPackageActionArgs(null, force)); } catch (Exception ex) { log.Error(ex); result = ActionResult.Error; } try { if (action.ExecutePackageActionSteps(package, force, target) == ActionResult.Error) { throw new Exception(); } } catch { log.Error($"Uninstall package action failed to execute for package '{package.Name}'."); result = ActionResult.Error; } foreach (var file in package.Files) { if (file.RelativeDestinationPath == "tap" || file.RelativeDestinationPath.ToLower() == "tap.exe") // ignore tap.exe as it is not meant to be overwritten. { continue; } string fullPath; if (package.IsSystemWide()) { fullPath = Path.Combine(PackageDef.SystemWideInstallationDirectory, file.RelativeDestinationPath); } else { fullPath = Path.Combine(destination, file.RelativeDestinationPath); } if (filesToRemain.Contains(file.RelativeDestinationPath)) { log.Debug("Skipping deletion of file '{0}' since it is required by another plugin package.", file.RelativeDestinationPath); continue; } try { log.Debug("Deleting file '{0}'.", file.RelativeDestinationPath); File.Delete(fullPath); } catch (Exception e) { log.Debug(e); result = ActionResult.Error; } DeleteEmptyDirectory(new FileInfo(fullPath).Directory); } var packageFile = PackageDef.GetDefaultPackageMetadataPath(package, target); if (!File.Exists(packageFile)) { // TAP 8.x support: packageFile = $"Package Definitions/{package.Name}.package.xml"; } if (File.Exists(packageFile)) { log.Debug("Deleting file '{0}'.", packageFile); File.Delete(packageFile); DeleteEmptyDirectory(new FileInfo(packageFile).Directory); } return(result); }