using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Win32; using Plume.Core.Logging; namespace ShuttleInstaller { public abstract class ShuttleInstaller : IShuttleInstaller { protected const string ShuttlePackageName = "com.ubisoft.adobe.cep.server"; protected const string HandledShuttlePackageVersion = "1.1.6"; private const string ManifestFileName = "manifest.xml"; private const string VersionFileName = "version.txt"; public string InstallationFolder { get; } public bool IsProperlyInstalled { get; private set; } = false; public string ShuttleVersion => HandledShuttlePackageVersion; protected ShuttleInstaller() { string appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); InstallationFolder = Path.Combine(appDataFolder, "Adobe/CEP/extensions", ShuttlePackageName); } public void Install(ILogger logger) { logger.Info($"Attempting to install \"{ShuttlePackageName}\"..."); if (Directory.Exists(InstallationFolder)) { logger.Error($"Error while installing: a previous installation is already present. Did you forget to call {nameof(Uninstall)}?"); return; } Directory.CreateDirectory(InstallationFolder); InstallFiles(logger); SetRegistryKey(logger); } // TODO: We do this because Shuttle is not a signed extension (yet?) private void SetRegistryKey(ILogger logger) { const string keyPath = @"Software\Adobe\CSXS.9"; // TODO: Will only work with AE 2019 const string keyName = @"PlayerDebugMode"; const string keyValue = "1"; logger.Debug("Attempting to set registry key..."); RegistryKey key; try { key = Registry.CurrentUser.CreateSubKey(keyPath); } catch (Exception e) { throw new InvalidOperationException($"Unable to create registry key '{keyName}' with value '{keyValue}' at '{keyPath}'. Did you try with Admin permissions?", e); } if (key == null) { throw new InvalidOperationException($"Unable to get registry key '{keyName}' with value '{keyValue}' at '{keyPath}'. Did you try with Admin permissions?"); } try { key.SetValue(keyName, keyValue); key.Close(); } catch (Exception e) { throw new InvalidOperationException($"Unable to set registry key '{keyName}' with value '{keyValue}' at '{keyPath}'. Did you try with Admin permissions?", e); } logger.Debug("Registry key properly set!"); } public abstract void InstallFiles(ILogger logger); public void CheckInstallation(ILogger logger) { logger.Debug($"Checking installation of \"{ShuttlePackageName}\"..."); IsProperlyInstalled = false; if (!Directory.Exists(InstallationFolder)) { logger.Debug($"\"{ShuttlePackageName}\" is not installed."); return; } ICollection installedFiles = Directory.EnumerateFiles(InstallationFolder, "*.*", SearchOption.AllDirectories).ToList(); logger.Info($"{installedFiles.Count} files installed in folder at \"{InstallationFolder}\"."); string manifestFilePath = installedFiles.FirstOrDefault(f => Path.GetFileName(f.ToLowerInvariant()) == ManifestFileName); if (string.IsNullOrEmpty(manifestFilePath)) { logger.Error($"File '{ManifestFileName}' is missing from \"{ShuttlePackageName}\"."); return; } string versionFilePath = installedFiles.FirstOrDefault(f => Path.GetFileName(f.ToLowerInvariant()) == VersionFileName); if (string.IsNullOrEmpty(versionFilePath)) { logger.Error($"File '{VersionFileName}' is missing from \"{ShuttlePackageName}\"."); return; } string packageVersion = File.ReadAllText(versionFilePath); if (packageVersion != HandledShuttlePackageVersion) { logger.Error($"\"{ShuttlePackageName}\" is at invalid version '{packageVersion}'. Only version '{HandledShuttlePackageVersion}' is handled."); return; } logger.Debug($"{ShuttlePackageName} is properly installed."); IsProperlyInstalled = true; } public void Uninstall(ILogger logger) { logger.Info($"Attempting to uninstall \"{ShuttlePackageName}\"..."); if (Directory.Exists(InstallationFolder)) { Directory.Delete(InstallationFolder, recursive: true); } logger.Info($"\"{ShuttlePackageName}\" was uninstalled."); } } }