/// <summary> /// Tries to install a plugin from 'path', throws an exception on error. /// </summary> internal static PackageDef InstallPluginPackage(string target, string path) { checkExtension(path); checkFileExists(path); var package = PackageDef.FromPackage(path); var destination = package.IsSystemWide() ? PackageDef.SystemWideInstallationDirectory : target; try { if (Path.GetExtension(path).ToLower().EndsWith("tappackages")) // This is a bundle { var tempDir = Path.GetTempPath(); var bundleFiles = UnpackPackage(path, tempDir); foreach (var file in bundleFiles) { UnpackPackage(file, destination); } } else { UnpackPackage(path, destination); } } catch (Exception e) { log.Error($"Install failed to execute for '{package.Name}'."); tryUninstall(path, package, target); throw new Exception($"Failed to install package '{path}'.", e); } var pi = new PluginInstaller(); if (pi.ExecuteAction(package, "install", false, target) == ActionResult.Error) { log.Error($"Install package action failed to execute for '{package.Name}'."); tryUninstall(path, package, target); throw new Exception($"Failed to install package '{path}'."); } CustomPackageActionHelper.RunCustomActions(package, PackageActionStage.Install, new CustomPackageActionArgs(null, false)); return(package); }
/// <summary> /// Creates a *.TapPackage file from the definition in this PackageDef. /// </summary> static public void CreatePackage(this PackageDef pkg, string path) { foreach (PackageFile file in pkg.Files) { if (!File.Exists(file.FileName)) { log.Error("{0}: File '{1}' not found", pkg.Name, file.FileName); throw new InvalidDataException(); } } if (pkg.Files.Any(s => s.HasCustomData <MissingPackageData>())) { bool resolved = true; foreach (var file in pkg.Files) { while (file.HasCustomData <MissingPackageData>()) { MissingPackageData missingPackageData = file.GetCustomData <MissingPackageData>().FirstOrDefault(); if (missingPackageData.TryResolve(out ICustomPackageData customPackageData)) { file.CustomData.Add(customPackageData); } else { resolved = false; log.Error($"Missing plugin to handle XML Element '{missingPackageData.XmlElement.Name.LocalName}' on file {file.FileName}. (Line {missingPackageData.GetLine()})"); } file.CustomData.Remove(missingPackageData); } } if (!resolved) { throw new ArgumentException("Missing plugins to handle XML elements specified in input package.xml..."); } } string tempDir = Path.GetTempPath() + Path.GetRandomFileName(); Directory.CreateDirectory(tempDir); log.Debug("Using temporary folder at '{0}'", tempDir); try { UpdateVersionInfo(tempDir, pkg.Files, pkg.Version); // License Inject // Obfuscate // Sign CustomPackageActionHelper.RunCustomActions(pkg, PackageActionStage.Create, new CustomPackageActionArgs(tempDir, false)); // Concat license required from all files. But only if the property has not manually been set. if (string.IsNullOrEmpty(pkg.LicenseRequired)) { var licenses = pkg.Files.Select(f => f.LicenseRequired).Where(l => l != null).ToList(); pkg.LicenseRequired = string.Join(", ", licenses.Distinct().Select(l => LicenseBase.FormatFriendly(l, false)).ToList()); } log.Info("Creating OpenTAP package."); pkg.Compress(path, pkg.Files); } finally { FileSystemHelper.DeleteDirectory(tempDir); } }
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); }