From 766fa23cc0065ecd0484cdb513c0aa1d83535919 Mon Sep 17 00:00:00 2001 From: ShrlAlgo <903524121@qq.com> Date: Tue, 20 Jan 2026 16:03:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=B0=83=E6=95=B4=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95=E8=B0=83=E8=AF=95=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- AddInManager/AIM.cs | 12 ++---- AddInManager/Addin.cs | 6 +-- AddInManager/AddinManager.cs | 44 +++++++++------------- AddInManager/AddinsApplication.cs | 8 ++-- AddInManager/AddinsCommand.cs | 8 ++-- AddInManager/AssemLoader.cs | 48 ++++++------------------ AddInManager/{IniFile.cs => InitFile.cs} | 4 +- AddinManager.iss | 2 +- 9 files changed, 48 insertions(+), 87 deletions(-) rename AddInManager/{IniFile.cs => InitFile.cs} (98%) diff --git a/.gitignore b/.gitignore index 9491a2f..6b3f12b 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,5 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd +/Setup diff --git a/AddInManager/AIM.cs b/AddInManager/AIM.cs index ca7f6f2..58a5f09 100644 --- a/AddInManager/AIM.cs +++ b/AddInManager/AIM.cs @@ -89,8 +89,7 @@ namespace AddInManager } else { - var externalCommand = instanceObj as IExternalCommand; - if (externalCommand == null) + if (instanceObj is not IExternalCommand externalCommand) { message = $"{className} 没有实现 IExternalCommand 接口"; result = Result.Failed; @@ -110,13 +109,8 @@ namespace AddInManager } finally { - // 确保清理工作安全执行 - try - { - assemLoader.UnhookAssemblyResolve(); - assemLoader.CopyGeneratedFilesBack(); - } - catch { /* 忽略清理时的错误,防止掩盖主异常 */ } + assemLoader.UnhookAssemblyResolve(); + assemLoader.CopyGeneratedFilesBack(); } return result; } diff --git a/AddInManager/Addin.cs b/AddInManager/Addin.cs index d274c55..a7b6eed 100644 --- a/AddInManager/Addin.cs +++ b/AddInManager/Addin.cs @@ -42,7 +42,7 @@ namespace AddInManager } } - public void SaveToLocalIni(IniFile file) + public void SaveToLocalIni(InitFile file) { if (ItemList == null || ItemList.Count == 0) { @@ -74,7 +74,7 @@ namespace AddInManager file.Write("ExternalApplications", "EACount", num2); } - private void WriteExternalCommand(IniFile file, AddinItem item, int number) + private void WriteExternalCommand(InitFile file, AddinItem item, int number) { file.Write("ExternalCommands", $"ECName{number}", item.Name); file.Write("ExternalCommands", $"ECClassName{number}", item.FullClassName); @@ -82,7 +82,7 @@ namespace AddInManager file.Write("ExternalCommands", $"ECDescription{number}", item.Description); } - private void WriteExternalApplication(IniFile file, AddinItem item, int number) + private void WriteExternalApplication(InitFile file, AddinItem item, int number) { file.Write("ExternalApplications", $"EAClassName{number}", item.FullClassName); file.Write("ExternalApplications", $"EAAssembly{number}", item.AssemblyName); diff --git a/AddInManager/AddinManager.cs b/AddInManager/AddinManager.cs index 6b63af3..00346bd 100644 --- a/AddInManager/AddinManager.cs +++ b/AddInManager/AddinManager.cs @@ -28,34 +28,27 @@ namespace AddInManager ReadAddinsFromAimIni(); } - public IniFile AimIniFile { get; set; } + public InitFile AimJsonFile { get; set; } - public IniFile RevitIniFile { get; set; } + public InitFile RevitIniFile { get; set; } private void GetIniFilePaths() { //var folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); var folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var appFolder = Path.Combine(folderPath, Resources.AppFolder); - // switch from INI to JSON storage - var iniFilePath = Path.Combine(appFolder, "AimInternal.json"); - AimIniFile = new IniFile(iniFilePath); - - // If an old INI exists, migrate it to JSON (one-time) + var jsonFilePath = Path.Combine(appFolder, "AimInternal.json"); + AimJsonFile = new InitFile(jsonFilePath); try { var oldIniPath = Path.Combine(appFolder, "AimInternal.ini"); - if (File.Exists(oldIniPath) && !File.Exists(iniFilePath)) + if (File.Exists(oldIniPath) && !File.Exists(jsonFilePath)) { - var oldIni = new IniFile(oldIniPath); - // populate commands/applications from old INI + var oldIni = new InitFile(oldIniPath); Commands.ReadItems(oldIni); Applications.ReadItems(oldIni); - // save to new JSON store - SaveToPersistentStore(iniFilePath); - - // backup old INI + SaveToPersistentStore(jsonFilePath); try { var backupPath = oldIniPath + ".bak"; @@ -77,16 +70,15 @@ namespace AddInManager var currentProcess = Process.GetCurrentProcess(); var fileName = currentProcess.MainModule.FileName; var revitIniFilePath = fileName.Replace(".exe", ".ini"); - RevitIniFile = new IniFile(revitIniFilePath); + RevitIniFile = new InitFile(revitIniFilePath); } public void ReadAddinsFromAimIni() { - // try load from persistent JSON store; if fails, fall back to legacy INI-format reader - if (!LoadFromPersistentStore(AimIniFile.FilePath)) + if (!LoadFromPersistentStore(AimJsonFile.FilePath)) { - Commands.ReadItems(AimIniFile); - Applications.ReadItems(AimIniFile); + Commands.ReadItems(AimJsonFile); + Applications.ReadItems(AimJsonFile); } } @@ -152,11 +144,11 @@ namespace AddInManager // ensure file exists try { - if (!File.Exists(AimIniFile.FilePath)) + if (!File.Exists(AimJsonFile.FilePath)) { - new FileInfo(AimIniFile.FilePath).Directory?.Create(); - FileUtils.CreateFile(AimIniFile.FilePath); - FileUtils.SetWriteable(AimIniFile.FilePath); + new FileInfo(AimJsonFile.FilePath).Directory?.Create(); + FileUtils.CreateFile(AimJsonFile.FilePath); + FileUtils.SetWriteable(AimJsonFile.FilePath); } } catch (Exception) @@ -165,10 +157,10 @@ namespace AddInManager } // save to persistent JSON store; if fails, fall back to legacy INI writer - if (!SaveToPersistentStore(AimIniFile.FilePath)) + if (!SaveToPersistentStore(AimJsonFile.FilePath)) { - Commands.Save(AimIniFile); - Applications.Save(AimIniFile); + Commands.Save(AimJsonFile); + Applications.Save(AimJsonFile); } } diff --git a/AddInManager/AddinsApplication.cs b/AddInManager/AddinsApplication.cs index e17b324..46a550d 100644 --- a/AddInManager/AddinsApplication.cs +++ b/AddInManager/AddinsApplication.cs @@ -2,7 +2,7 @@ { public class AddinsApplication : Addins { - public void ReadItems(IniFile file) + public void ReadItems(InitFile file) { var num = file.ReadInt("ExternalApplications", "EACount"); var i = 1; @@ -13,7 +13,7 @@ SortAddin(); } - private bool ReadExternalApplication(IniFile file, int nodeNumber) + private bool ReadExternalApplication(InitFile file, int nodeNumber) { var text = file.ReadString("ExternalApplications", $"EAClassName{nodeNumber}"); var text2 = file.ReadString("ExternalApplications", $"EAAssembly{nodeNumber}"); @@ -30,7 +30,7 @@ return true; } - public void Save(IniFile file) + public void Save(InitFile file) { file.WriteSection("ExternalApplications"); file.Write("ExternalApplications", "EACount", m_maxCount); @@ -52,7 +52,7 @@ file.Write("ExternalApplications", "EACount", num); } - private bool WriteExternalApplication(IniFile file, AddinItem item, int number) + private bool WriteExternalApplication(InitFile file, AddinItem item, int number) { file.Write("ExternalApplications", $"EAClassName{number}", item.FullClassName); file.Write("ExternalApplications", $"EAAssembly{number}", item.AssemblyPath); diff --git a/AddInManager/AddinsCommand.cs b/AddInManager/AddinsCommand.cs index f7f59f1..bdd8cab 100644 --- a/AddInManager/AddinsCommand.cs +++ b/AddInManager/AddinsCommand.cs @@ -2,7 +2,7 @@ { public class AddinsCommand : Addins { - public void ReadItems(IniFile file) + public void ReadItems(InitFile file) { var num = file.ReadInt("ExternalCommands", "ECCount"); var i = 1; @@ -13,7 +13,7 @@ SortAddin(); } - private bool ReadExternalCommand(IniFile file, int nodeNumber) + private bool ReadExternalCommand(InitFile file, int nodeNumber) { var text = file.ReadString("ExternalCommands", $"ECName{nodeNumber}"); var text2 = file.ReadString("ExternalCommands", $"ECAssembly{nodeNumber}"); @@ -33,7 +33,7 @@ return true; } - public void Save(IniFile file) + public void Save(InitFile file) { file.WriteSection("ExternalCommands"); file.Write("ExternalCommands", "ECCount", m_maxCount); @@ -55,7 +55,7 @@ file.Write("ExternalCommands", "ECCount", num); } - private bool WriteExternalCommand(IniFile file, AddinItem item, int number) + private bool WriteExternalCommand(InitFile file, AddinItem item, int number) { file.Write("ExternalCommands", $"ECName{number}", item.Name); file.Write("ExternalCommands", $"ECClassName{number}", item.FullClassName); diff --git a/AddInManager/AssemLoader.cs b/AddInManager/AssemLoader.cs index 801ac15..0d36aa8 100644 --- a/AddInManager/AssemLoader.cs +++ b/AddInManager/AssemLoader.cs @@ -17,7 +17,6 @@ namespace AddInManager private Dictionary m_copiedFiles; private bool m_parsingOnly; - // 移除硬编码的 .NET 2.0 路径,改用更通用的方式(虽然在Revit中通常不依赖这个) private static string m_dotnetDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); public static string m_resolvedAssemPath = string.Empty; @@ -30,26 +29,27 @@ namespace AddInManager m_copiedFiles = new Dictionary(); } - // ... CopyGeneratedFilesBack 保持不变 ... public void CopyGeneratedFilesBack() { - if (string.IsNullOrEmpty(TempFolder) || !Directory.Exists(TempFolder)) return; - var files = Directory.GetFiles(TempFolder, "*.*", SearchOption.AllDirectories); - foreach (var text in files) + foreach(var text in files) { - if (m_copiedFiles.ContainsKey(text)) + if(m_copiedFiles.ContainsKey(text)) { var dateTime = m_copiedFiles[text]; var fileInfo = new FileInfo(text); - if (fileInfo.LastWriteTime > dateTime) + if(fileInfo.LastWriteTime > dateTime) { var text2 = text.Remove(0, TempFolder.Length); var text3 = OriginalFolder + text2; FileUtils.CopyFile(text, text3); } + } else + { + var text4 = text.Remove(0, TempFolder.Length); + var text5 = OriginalFolder + text4; + FileUtils.CopyFile(text, text5); } - // 新生成的文件不建议盲目拷回,可能会污染源目录,视需求而定 } } @@ -77,10 +77,6 @@ namespace AddInManager TempFolder = FileUtils.CreateTempFolder(stringBuilder.ToString()); - // 【建议】在此处,除了复制主DLL,最好把同目录下的所有 .dll 都复制过去 - // 这样可以避免 AssemblyResolve 频繁触发,解决大部分 NuGet 依赖问题 - // CopyAllDllsToTemp(OriginalFolder, TempFolder); // 这是一个建议实现的辅助方法 - var assembly = CopyAndLoadAddin(originalFilePath, parsingOnly); if (null == assembly || !IsAPIReferenced(assembly)) { @@ -99,29 +95,17 @@ namespace AddInManager { m_refedFolders.Add(directoryName); } - var list = new List(); - // 假设 FileUtils.CopyFileToFolder 会处理文件复制 - // 关键点:如果你的 FileUtils 不支持复制子文件夹(如 zh-CN),资源加载依然会失败 destPath = FileUtils.CopyFileToFolder(srcFilePath, TempFolder, onlyCopyRelated, list); - if (string.IsNullOrEmpty(destPath)) { return null; } foreach (var fileInfo in list) { - if (!m_copiedFiles.ContainsKey(fileInfo.FullName)) - m_copiedFiles.Add(fileInfo.FullName, fileInfo.LastWriteTime); + m_copiedFiles.Add(fileInfo.FullName, fileInfo.LastWriteTime); } } - else - { - // 如果文件已存在,计算目标路径 - string fileName = Path.GetFileName(srcFilePath); - destPath = Path.Combine(TempFolder, fileName); - } - return LoadAddin(destPath); } @@ -131,10 +115,7 @@ namespace AddInManager try { Monitor.Enter(this); - // 【关键修改 1】使用 LoadFrom 而不是 LoadFile - // LoadFrom 会自动在 filePath 所在的目录中查找依赖项,这解决了大部分 NuGet 包加载失败的问题 - // LoadFile 这是一个纯粹的文件加载,不带上下文,不会去旁边找依赖 - assembly = Assembly.LoadFrom(filePath); + assembly = Assembly.LoadFile(filePath); } catch (Exception ex) { @@ -157,9 +138,6 @@ namespace AddInManager var assemblyNameObj = new AssemblyName(args.Name); var simpleName = assemblyNameObj.Name; - // 【关键修改 2】绝对不要在 AssemblyResolve 中手动处理 .resources - // 那个 "长度不能小于0" 的错误就是因为这里返回了错误的东西或者试图去加载主程序集 - // 如果请求的是 .resources,直接返回 null,让 CLR 自己去临时目录的子文件夹里找 if (simpleName.EndsWith(".resources", StringComparison.OrdinalIgnoreCase) || args.Name.Contains(".resources")) { @@ -183,8 +161,6 @@ namespace AddInManager return assembly; } - // 4. 如果还没找到,处理一些特殊情况(比如 XMLSerializers) - // 这里的逻辑可以保留,但通常用处不大 if (simpleName.EndsWith(".XmlSerializers", StringComparison.OrdinalIgnoreCase)) { // 忽略序列化程序集请求 @@ -222,14 +198,12 @@ namespace AddInManager { var extensions = new string[] { ".dll", ".exe" }; - // 1. 在 .NET 框架目录找 (通常不需要,System库会自动加载,但保留也没事) - /* + foreach (var ext in extensions) { string path = Path.Combine(m_dotnetDir, simpleName + ext); if (File.Exists(path)) return path; } - */ // 2. 在所有引用过的源目录中找 foreach (var ext in extensions) diff --git a/AddInManager/IniFile.cs b/AddInManager/InitFile.cs similarity index 98% rename from AddInManager/IniFile.cs rename to AddInManager/InitFile.cs index 59a6f8f..96e816a 100644 --- a/AddInManager/IniFile.cs +++ b/AddInManager/InitFile.cs @@ -8,14 +8,14 @@ using System.Runtime.Serialization; namespace AddInManager { - public class IniFile + public class InitFile { public string FilePath { get; } private readonly bool m_isJson; private Dictionary> m_jsonData; - public IniFile(string filePath) + public InitFile(string filePath) { FilePath = filePath; m_isJson = string.Equals(Path.GetExtension(FilePath), ".json", StringComparison.OrdinalIgnoreCase); diff --git a/AddinManager.iss b/AddinManager.iss index 977821b..7a7546f 100644 --- a/AddinManager.iss +++ b/AddinManager.iss @@ -4,7 +4,7 @@ ; 定义应用程序的名称 #define MyAppName "RevitAddinManager" ; 定义应用程序的版本号 -#define MyAppVersion "2.0.0" +#define MyAppVersion "3.0.0" ; 定义应用程序的发布者 #define MyAppPublisher "ShrlAlgo" ; 定义应用程序的网址