feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyName>PremiereConnectorInstaller</AssemblyName>
|
||||
<RootNamespace>PremiereConnectorInstaller</RootNamespace>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<SelfContained>true</SelfContained>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(ConnectorPackage)' != ''">
|
||||
<EmbeddedResource Include="$(ConnectorPackage)" LogicalName="MCPBridgeCEP.zxp" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="RequireConnectorPackage" BeforeTargets="BeforeBuild">
|
||||
<Error Condition="'$(ConnectorPackage)' == ''" Text="ConnectorPackage must point to a verified MCPBridgeCEP.zxp." />
|
||||
<Error Condition="!Exists('$(ConnectorPackage)')" Text="ConnectorPackage does not exist: $(ConnectorPackage)" />
|
||||
</Target>
|
||||
</Project>
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
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("<ExtensionManifest", StringComparison.Ordinal) ||
|
||||
!manifestText.Contains("ExtensionBundleId=\"com.mcp.premiere.bridge\"", StringComparison.Ordinal))
|
||||
throw new InvalidDataException("The connector package has an invalid CSXS/manifest.xml.");
|
||||
}
|
||||
|
||||
private static void RemoveConnector()
|
||||
{
|
||||
EnsureInsideCepRoot(Destination);
|
||||
if (Directory.Exists(Destination)) Directory.Delete(Destination, true);
|
||||
}
|
||||
|
||||
private static void EnsureInsideCepRoot(string path)
|
||||
{
|
||||
string root = CepRoot.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
||||
if (!path.StartsWith(root, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException("Refusing to modify files outside the Adobe CEP extensions folder.");
|
||||
}
|
||||
|
||||
private static bool IsPremiereRunning() => 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user