using System.Diagnostics; using System.IO.Compression; using System.Reflection; using Microsoft.Win32; namespace PremiereConnectorInstaller; internal static class Program { private const string ExtensionId = "MCPBridgeCEP"; private const string ResourceName = "MCPBridgeCEP.zxp"; [STAThread] private static int Main(string[] args) { bool verifyOnly = args.Contains("--verify-only", StringComparer.OrdinalIgnoreCase); if (verifyOnly) { try { VerifyEmbeddedPackage(); Console.WriteLine("Embedded connector package verified without installation."); return 0; } catch (Exception error) { Console.Error.WriteLine("Embedded connector package verification failed: " + error.Message); return 1; } } ApplicationConfiguration.Initialize(); bool quiet = args.Contains("--quiet", StringComparer.OrdinalIgnoreCase); bool uninstall = args.Contains("--uninstall", StringComparer.OrdinalIgnoreCase); try { if (uninstall) { if (IsPremiereRunning()) { Show(quiet, "Premiere Pro is running. Close it before removing the Connector.", MessageBoxIcon.Warning); return 3; } RemoveConnector(); Show( quiet, "Premiere Connector was removed. Adobe's shared debug setting was left unchanged for other CEP extensions. Remove the MCP server from your AI client separately if needed.", MessageBoxIcon.Information); return 0; } if (!quiet) { DialogResult answer = MessageBox.Show( "Install or repair the Premiere Connector for the current Windows account?\n\n" + "Close Premiere Pro first. Your media and projects are not accessed.", "Premiere Connector Setup", MessageBoxButtons.OKCancel, MessageBoxIcon.Information); if (answer != DialogResult.OK) return 2; } if (IsPremiereRunning()) { Show(quiet, "Premiere Pro is running. Close it, then run this installer again.", MessageBoxIcon.Warning); return 3; } InstallConnector(); Show( quiet, "Premiere Connector is installed.\n\n" + "Next: open Premiere Pro, choose Window > Extensions > MCP Bridge, then ask your AI assistant to verify the Premiere connection.", MessageBoxIcon.Information); return 0; } catch (Exception error) { Show(quiet, "Setup could not finish:\n\n" + error.Message, MessageBoxIcon.Error); return 1; } } private static string CepRoot => Path.GetFullPath(Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Adobe", "CEP", "extensions")); private static string Destination => Path.GetFullPath(Path.Combine(CepRoot, ExtensionId)); private static void InstallConnector() { EnsureInsideCepRoot(Destination); Directory.CreateDirectory(CepRoot); string staging = Path.Combine(CepRoot, $".{ExtensionId}-staging-{Guid.NewGuid():N}"); string backup = Path.Combine(CepRoot, $".{ExtensionId}-backup-{Guid.NewGuid():N}"); try { Directory.CreateDirectory(staging); ExtractEmbeddedPackage(staging); string manifest = Path.Combine(staging, "CSXS", "manifest.xml"); if (!File.Exists(manifest)) throw new InvalidDataException("The connector package is missing CSXS/manifest.xml."); if (Directory.Exists(Destination)) Directory.Move(Destination, backup); Directory.Move(staging, Destination); if (Directory.Exists(backup)) Directory.Delete(backup, true); for (int version = 9; version <= 14; version++) { using RegistryKey key = Registry.CurrentUser.CreateSubKey($@"SOFTWARE\Adobe\CSXS.{version}", true); key.SetValue("PlayerDebugMode", "1", RegistryValueKind.String); } } catch { if (!Directory.Exists(Destination) && Directory.Exists(backup)) Directory.Move(backup, Destination); throw; } finally { if (Directory.Exists(staging)) Directory.Delete(staging, true); if (Directory.Exists(backup)) Directory.Delete(backup, true); } } private static void ExtractEmbeddedPackage(string staging) { using Stream package = Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName) ?? throw new InvalidOperationException("The verified connector package is not embedded in this installer."); using var archive = new ZipArchive(package, ZipArchiveMode.Read); string root = Path.GetFullPath(staging).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; foreach (ZipArchiveEntry entry in archive.Entries) { string target = Path.GetFullPath(Path.Combine(staging, entry.FullName.Replace('/', Path.DirectorySeparatorChar))); if (!target.StartsWith(root, StringComparison.OrdinalIgnoreCase)) throw new InvalidDataException("The connector package contains an unsafe path."); if (string.IsNullOrEmpty(entry.Name)) { Directory.CreateDirectory(target); continue; } Directory.CreateDirectory(Path.GetDirectoryName(target)!); entry.ExtractToFile(target, true); } } // This is deliberately read-only: CI can execute the shipped single-file installer // and prove its embedded connector is structurally safe without touching the CEP // directory, registry, Premiere process state, or any project data. private static void VerifyEmbeddedPackage() { using Stream package = Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName) ?? throw new InvalidOperationException("The verified connector package is not embedded in this installer."); using var archive = new ZipArchive(package, ZipArchiveMode.Read); string validationRoot = Path.GetFullPath(Path.Combine(Path.GetTempPath(), "premiere-connector-validate")) .TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; ZipArchiveEntry? manifest = null; foreach (ZipArchiveEntry entry in archive.Entries) { string target = Path.GetFullPath(Path.Combine( validationRoot, entry.FullName.Replace('/', Path.DirectorySeparatorChar))); if (!target.StartsWith(validationRoot, StringComparison.OrdinalIgnoreCase)) throw new InvalidDataException("The connector package contains an unsafe path."); if (string.Equals(entry.FullName, "CSXS/manifest.xml", StringComparison.Ordinal)) manifest = entry; } if (manifest is null) throw new InvalidDataException("The connector package is missing CSXS/manifest.xml."); using var reader = new StreamReader(manifest.Open()); string manifestText = reader.ReadToEnd(); if (!manifestText.Contains(" Process.GetProcesses().Any(process => { try { return process.ProcessName.Contains("Adobe Premiere Pro", StringComparison.OrdinalIgnoreCase); } catch { return false; } }); private static void Show(bool quiet, string message, MessageBoxIcon icon) { if (quiet) Console.Error.WriteLine(message); else MessageBox.Show(message, "Premiere Connector Setup", MessageBoxButtons.OK, icon); } }