mirror of
https://github.com/ShrlAlgo/AddinManager.git
synced 2026-03-09 18:08:18 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b7a6e2772 | ||
|
|
766fa23cc0 | ||
|
|
681681c7ed |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -360,4 +360,5 @@ MigrationBackup/
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
/Setup
|
||||
|
||||
@@ -36,35 +36,75 @@ namespace AddInManager
|
||||
|
||||
private Result RunActiveCommand(ExternalCommandData data, ref string message, ElementSet elements)
|
||||
{
|
||||
// 防御性检查:确保 ActiveCmd 不为空
|
||||
if (this.ActiveCmd == null)
|
||||
{
|
||||
MessageBox.Show("错误:ActiveCmd 为 null");
|
||||
return Result.Failed;
|
||||
}
|
||||
|
||||
// 防御性检查:确保 ActiveCmdItem 不为空
|
||||
if (this.ActiveCmdItem == null)
|
||||
{
|
||||
MessageBox.Show("错误:ActiveCmdItem 为 null");
|
||||
return Result.Failed;
|
||||
}
|
||||
|
||||
var filePath = ActiveCmd.FilePath;
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
{
|
||||
MessageBox.Show($"错误:找不到文件 {filePath}");
|
||||
return Result.Failed;
|
||||
}
|
||||
|
||||
var assemLoader = new AssemLoader();
|
||||
Result result;
|
||||
Result result = Result.Failed; // 默认失败
|
||||
|
||||
try
|
||||
{
|
||||
assemLoader.HookAssemblyResolve();
|
||||
|
||||
var assembly = assemLoader.LoadAddinsToTempFolder(filePath, false);
|
||||
if (null == assembly)
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
message = "Assembly 加载失败,返回了 null";
|
||||
result = Result.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveTempFolder = assemLoader.TempFolder;
|
||||
var externalCommand = assembly.CreateInstance(ActiveCmdItem.FullClassName) as IExternalCommand;
|
||||
if (externalCommand == null)
|
||||
|
||||
string className = ActiveCmdItem.FullClassName;
|
||||
if (string.IsNullOrEmpty(className)) throw new Exception("类名为空");
|
||||
|
||||
var instanceObj = assembly.CreateInstance(className);
|
||||
|
||||
if (instanceObj == null)
|
||||
{
|
||||
message = $"无法创建实例: {className}。请检查类名是否正确或是否有无参构造函数。";
|
||||
result = Result.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveEC = externalCommand;
|
||||
result = ActiveEC.Execute(data, ref message, elements);
|
||||
if (instanceObj is not IExternalCommand externalCommand)
|
||||
{
|
||||
message = $"{className} 没有实现 IExternalCommand 接口";
|
||||
result = Result.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveEC = externalCommand;
|
||||
result = ActiveEC.Execute(data, ref message, elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString());
|
||||
MessageBox.Show($"执行异常:\n{ex.Message}\n\n堆栈:\n{ex.StackTrace}");
|
||||
result = Result.Failed;
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,10 +17,9 @@ namespace AddInManager
|
||||
private Dictionary<string, DateTime> m_copiedFiles;
|
||||
private bool m_parsingOnly;
|
||||
|
||||
// 移除硬编码的 .NET 2.0 路径,改用更通用的方式(虽然在Revit中通常不依赖这个)
|
||||
// 获取 .NET 运行时目录
|
||||
private static string m_dotnetDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
|
||||
|
||||
public static string m_resolvedAssemPath = string.Empty;
|
||||
private string m_revitAPIAssemblyFullName;
|
||||
|
||||
public AssemLoader()
|
||||
@@ -30,11 +29,10 @@ namespace AddInManager
|
||||
m_copiedFiles = new Dictionary<string, DateTime>();
|
||||
}
|
||||
|
||||
// ... CopyGeneratedFilesBack 保持不变 ...
|
||||
// 保持原有的文件回写逻辑不变
|
||||
public void CopyGeneratedFilesBack()
|
||||
{
|
||||
if (string.IsNullOrEmpty(TempFolder) || !Directory.Exists(TempFolder)) return;
|
||||
|
||||
if (!Directory.Exists(TempFolder)) return;
|
||||
var files = Directory.GetFiles(TempFolder, "*.*", SearchOption.AllDirectories);
|
||||
foreach (var text in files)
|
||||
{
|
||||
@@ -49,7 +47,7 @@ namespace AddInManager
|
||||
FileUtils.CopyFile(text, text3);
|
||||
}
|
||||
}
|
||||
// 新生成的文件不建议盲目拷回,可能会污染源目录,视需求而定
|
||||
// 注意:通常我们不希望把临时文件夹产生的所有垃圾文件都拷回源目录,视需求而定
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +63,7 @@ namespace AddInManager
|
||||
|
||||
public Assembly LoadAddinsToTempFolder(string originalFilePath, bool parsingOnly)
|
||||
{
|
||||
if (string.IsNullOrEmpty(originalFilePath) || originalFilePath.StartsWith("\\") || !File.Exists(originalFilePath))
|
||||
if (string.IsNullOrEmpty(originalFilePath) || !File.Exists(originalFilePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -75,12 +73,10 @@ namespace AddInManager
|
||||
var stringBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(originalFilePath));
|
||||
stringBuilder.Append(parsingOnly ? "-Parsing-" : "-Executing-");
|
||||
|
||||
// 1. 创建全新的临时文件夹 (基于时间戳,确保唯一)
|
||||
TempFolder = FileUtils.CreateTempFolder(stringBuilder.ToString());
|
||||
|
||||
// 【建议】在此处,除了复制主DLL,最好把同目录下的所有 .dll 都复制过去
|
||||
// 这样可以避免 AssemblyResolve 频繁触发,解决大部分 NuGet 依赖问题
|
||||
// CopyAllDllsToTemp(OriginalFolder, TempFolder); // 这是一个建议实现的辅助方法
|
||||
|
||||
// 2. 复制并加载
|
||||
var assembly = CopyAndLoadAddin(originalFilePath, parsingOnly);
|
||||
if (null == assembly || !IsAPIReferenced(assembly))
|
||||
{
|
||||
@@ -91,7 +87,9 @@ namespace AddInManager
|
||||
|
||||
private Assembly CopyAndLoadAddin(string srcFilePath, bool onlyCopyRelated)
|
||||
{
|
||||
var destPath = string.Empty;
|
||||
string destPath = string.Empty;
|
||||
|
||||
// 复制文件到临时目录
|
||||
if (!FileUtils.FileExistsInFolder(srcFilePath, TempFolder))
|
||||
{
|
||||
var directoryName = Path.GetDirectoryName(srcFilePath);
|
||||
@@ -99,29 +97,23 @@ namespace AddInManager
|
||||
{
|
||||
m_refedFolders.Add(directoryName);
|
||||
}
|
||||
|
||||
var list = new List<FileInfo>();
|
||||
// 假设 FileUtils.CopyFileToFolder 会处理文件复制
|
||||
// 关键点:如果你的 FileUtils 不支持复制子文件夹(如 zh-CN),资源加载依然会失败
|
||||
destPath = FileUtils.CopyFileToFolder(srcFilePath, TempFolder, onlyCopyRelated, list);
|
||||
|
||||
if (string.IsNullOrEmpty(destPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
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[fileInfo.FullName] = fileInfo.LastWriteTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果文件已存在,计算目标路径
|
||||
string fileName = Path.GetFileName(srcFilePath);
|
||||
destPath = Path.Combine(TempFolder, fileName);
|
||||
// 如果文件已存在(极少情况,因为是新Temp目录),构造目标路径
|
||||
destPath = Path.Combine(TempFolder, Path.GetFileName(srcFilePath));
|
||||
}
|
||||
|
||||
// 加载复制后的文件
|
||||
return LoadAddin(destPath);
|
||||
}
|
||||
|
||||
@@ -130,81 +122,60 @@ namespace AddInManager
|
||||
Assembly assembly = null;
|
||||
try
|
||||
{
|
||||
Monitor.Enter(this);
|
||||
// 【关键修改 1】使用 LoadFrom 而不是 LoadFile
|
||||
// LoadFrom 会自动在 filePath 所在的目录中查找依赖项,这解决了大部分 NuGet 包加载失败的问题
|
||||
// LoadFile 这是一个纯粹的文件加载,不带上下文,不会去旁边找依赖
|
||||
assembly = Assembly.LoadFrom(filePath);
|
||||
// 【核心修改】:使用字节流加载,而不是 LoadFile
|
||||
// 这样可以避免文件锁定,并且每次 Load 都会视为新的程序集实例
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
byte[] assemblyBytes = File.ReadAllBytes(filePath);
|
||||
byte[] pdbBytes = null;
|
||||
|
||||
// 尝试加载 PDB 以支持调试
|
||||
string pdbPath = Path.ChangeExtension(filePath, "pdb");
|
||||
if (File.Exists(pdbPath))
|
||||
{
|
||||
pdbBytes = File.ReadAllBytes(pdbPath);
|
||||
}
|
||||
|
||||
// 使用 Load(bytes, pdbBytes)
|
||||
assembly = Assembly.Load(assemblyBytes, pdbBytes);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 增加简单的错误输出,方便调试
|
||||
Debug.WriteLine($"LoadAddin Failed: {filePath}, Error: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
return assembly;
|
||||
}
|
||||
|
||||
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
Assembly assembly = null;
|
||||
lock (this)
|
||||
// 防止递归或死循环
|
||||
string assemblyName = new AssemblyName(args.Name).Name;
|
||||
|
||||
// 忽略资源文件
|
||||
if (assemblyName.EndsWith(".resources") || assemblyName.EndsWith(".XmlSerializers"))
|
||||
return null;
|
||||
|
||||
// 1. 在临时文件夹中寻找依赖项
|
||||
// 因为主程序是字节流加载的,它不知道自己在 TempFolder,必须我们告诉它去那里找
|
||||
string foundPath = SearchAssemblyFileInTempFolder(assemblyName);
|
||||
|
||||
if (!string.IsNullOrEmpty(foundPath))
|
||||
{
|
||||
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"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. 先在临时目录找
|
||||
var text = SearchAssemblyFileInTempFolder(simpleName);
|
||||
if (File.Exists(text))
|
||||
{
|
||||
return LoadAddin(text);
|
||||
}
|
||||
|
||||
// 2. 临时目录没有,去源目录找
|
||||
text = SearchAssemblyFileInOriginalFolders(simpleName);
|
||||
|
||||
// 3. 如果源目录找到了,复制到临时目录并加载
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
assembly = CopyAndLoadAddin(text, true);
|
||||
return assembly;
|
||||
}
|
||||
|
||||
// 4. 如果还没找到,处理一些特殊情况(比如 XMLSerializers)
|
||||
// 这里的逻辑可以保留,但通常用处不大
|
||||
if (simpleName.EndsWith(".XmlSerializers", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// 忽略序列化程序集请求
|
||||
return null;
|
||||
}
|
||||
|
||||
// 5. 【可选】最后尝试手动弹窗选择(原代码逻辑),
|
||||
// 但通常对于依赖项来说,弹窗很烦人,建议只针对主程序集弹窗,或者直接返回null
|
||||
// 如果这是为了解决找不到依赖的问题,上面 LoadFrom 改好后这里应该很少进来了
|
||||
// 只有当你确实需要弹窗时保留下面代码
|
||||
/*
|
||||
var assemblySelector = new Wpf.AssemblySelectorWindow(args.Name);
|
||||
if (assemblySelector.ShowDialog() == true)
|
||||
{
|
||||
text = assemblySelector.ResultPath;
|
||||
assembly = CopyAndLoadAddin(text, true);
|
||||
}
|
||||
*/
|
||||
// 找到依赖项后,同样使用字节流加载!
|
||||
// 这样保证主程序集和依赖程序集都在“无上下文”的环境中匹配
|
||||
return LoadAddin(foundPath);
|
||||
}
|
||||
return assembly;
|
||||
|
||||
// 2. 如果临时文件夹没有,去源文件夹找 (并复制过来)
|
||||
foundPath = SearchAssemblyFileInOriginalFolders(assemblyName);
|
||||
if (!string.IsNullOrEmpty(foundPath))
|
||||
{
|
||||
return CopyAndLoadAddin(foundPath, true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string SearchAssemblyFileInTempFolder(string simpleName)
|
||||
@@ -215,43 +186,35 @@ namespace AddInManager
|
||||
string path = Path.Combine(TempFolder, simpleName + ext);
|
||||
if (File.Exists(path)) return path;
|
||||
}
|
||||
return string.Empty;
|
||||
return null;
|
||||
}
|
||||
|
||||
private string SearchAssemblyFileInOriginalFolders(string simpleName)
|
||||
{
|
||||
var extensions = new string[] { ".dll", ".exe" };
|
||||
|
||||
// 1. 在 .NET 框架目录找 (通常不需要,System库会自动加载,但保留也没事)
|
||||
/*
|
||||
// 1. 系统目录 (通常不需要,System dll 会自动解析,但保留以防万一)
|
||||
foreach (var ext in extensions)
|
||||
{
|
||||
string path = Path.Combine(m_dotnetDir, simpleName + ext);
|
||||
if (File.Exists(path)) return path;
|
||||
}
|
||||
*/
|
||||
|
||||
// 2. 在所有引用过的源目录中找
|
||||
// 2. 所有引用过的源文件夹
|
||||
foreach (var ext in extensions)
|
||||
{
|
||||
foreach (var folder in m_refedFolders)
|
||||
{
|
||||
string path = Path.Combine(folder, simpleName + ext);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
if (File.Exists(path)) return path;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 原代码中关于 Regression 的逻辑(看起来是特定环境的,如果不需要建议删除)
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsAPIReferenced(Assembly assembly)
|
||||
{
|
||||
// 保持原逻辑不变
|
||||
if (string.IsNullOrEmpty(m_revitAPIAssemblyFullName))
|
||||
{
|
||||
foreach (var assembly2 in AppDomain.CurrentDomain.GetAssemblies())
|
||||
@@ -263,7 +226,7 @@ namespace AddInManager
|
||||
}
|
||||
}
|
||||
}
|
||||
// 防止未加载 RevitAPI 时崩溃
|
||||
// 如果还没加载 RevitAPI (极其罕见),通过
|
||||
if (string.IsNullOrEmpty(m_revitAPIAssemblyFullName)) return true;
|
||||
|
||||
foreach (var assemblyName in assembly.GetReferencedAssemblies())
|
||||
|
||||
@@ -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<string, Dictionary<string, string>> m_jsonData;
|
||||
|
||||
public IniFile(string filePath)
|
||||
public InitFile(string filePath)
|
||||
{
|
||||
FilePath = filePath;
|
||||
m_isJson = string.Equals(Path.GetExtension(FilePath), ".json", StringComparison.OrdinalIgnoreCase);
|
||||
@@ -4,7 +4,7 @@
|
||||
; 定义应用程序的名称
|
||||
#define MyAppName "RevitAddinManager"
|
||||
; 定义应用程序的版本号
|
||||
#define MyAppVersion "1.0.0.0"
|
||||
#define MyAppVersion "3.2.0"
|
||||
; 定义应用程序的发布者
|
||||
#define MyAppPublisher "ShrlAlgo"
|
||||
; 定义应用程序的网址
|
||||
|
||||
Reference in New Issue
Block a user