using Microsoft.Win32; using Launcher.Next.Core; namespace Launcher.Next.Autodesk; public interface IRegistryReader { object? GetValue(string path, string name); } public sealed class WindowsRegistryReader : IRegistryReader { public object? GetValue(string path, string name) => Registry.LocalMachine.OpenSubKey(path)?.GetValue(name); } public sealed class PlantProductDiscovery(IRegistryReader registry) : IProductDiscovery { public ProductInstallation? DiscoverPlant3D(int year) { var install = registry.GetValue($@"SOFTWARE\Autodesk\AutoCAD\R25.1\ACAD-xxxx:409", "InstallDir") as string; if (string.IsNullOrWhiteSpace(install)) return null; var exe = Path.Combine(install, "acad.exe"); return File.Exists(exe) ? new(exe, year.ToString(), "x64", []) : null; } } public sealed class StartupScriptBuilder : IStartupScriptBuilder { public string BuildNetloadScript(string root, string entry) { var full = Path.GetFullPath(Path.Combine(root, entry)); if (!full.StartsWith(Path.GetFullPath(root) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) || !File.Exists(full)) throw new InvalidOperationException("UNTRUSTED_ENTRY_PATH"); return $"_.NETLOAD\n\"{full.Replace("\"", "\\\"")}\"\n"; } public string BuildAutomationScript(ResolvedAutomationScriptPaths paths) { var fixture = Path.GetFullPath(paths.FixtureOrthoDwg); if (!File.Exists(fixture)) throw new InvalidOperationException("AUTOMATION_FIXTURE_NOT_FOUND"); var quote = (string value) => "\"" + value.Replace("\"", "\\\"") + "\""; var dialogFreeOpen = "_.FILEDIA\n0\n_.CMDDIA\n0\n"; var diagnostic = paths.Diagnostic ? "_.CMDECHO\n1\n_.NOMUTT\n0\n_.LOGFILEMODE\n1\n" : string.Empty; var commands = paths.Apply ? "_.UNDO\n_MARK\nPXP-OA\nPXP-OA\n_.UNDO\n_BACK\n" : paths.Diagnostic ? "PHP_REC_AUTOMATION_BEFORE_PXP_1\nPXP-OA\nPHP_REC_AUTOMATION_AFTER_PXP_1\nPHP_REC_AUTOMATION_BEFORE_PXP_2\nPXP-OA\nPHP_REC_AUTOMATION_AFTER_PXP_2\n" : "PXP-OA\nPXP-OA\n"; return dialogFreeOpen + "_.OPEN\n" + quote(fixture) + "\n" + diagnostic + BuildNetloadScript(paths.ValidatedPackageRoot, paths.EntryAssembly) + "PHP_REC_AUTOMATION_PREPARE\n" + commands + "PHP_REC_AUTOMATION_FINALIZE\n"; } } public sealed class DryRunAutodeskProcessLauncher : IAutodeskProcessLauncher { public PreparedLaunch Prepare(LaunchRequest r) { if (!r.DryRun) throw new InvalidOperationException("PROCESS_START_DISABLED_IN_FOUNDATION"); var startInfo = new System.Diagnostics.ProcessStartInfo { FileName = r.Product.ExecutablePath, WorkingDirectory = Path.GetDirectoryName(r.Product.ExecutablePath)!, UseShellExecute = false }; startInfo.ArgumentList.Add("/product"); startInfo.ArgumentList.Add("PLNT3D"); startInfo.ArgumentList.Add("/p"); startInfo.ArgumentList.Add(r.Profile); startInfo.ArgumentList.Add("/b"); startInfo.ArgumentList.Add(r.StartupScriptPath); return new(startInfo.FileName, startInfo.ArgumentList.ToArray(), startInfo.WorkingDirectory, false); } }