/*------------------------------------------------------------------------- * 功能描述:ButtonAssemblyManager * 作者:xulisong * 创建时间: 2019/7/25 13:06:54 * 版本号:v1.0 * -------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Autodesk.Revit.UI; namespace FWindSoft.Revit.Menu { public class ButtonAssemblyManager { public static MenuConfig GetMenuConfigIsolate(string path) { return DoaminProxy.NewDomainExecute(ButtonAssemblyManager.GetMenuConfig, path); } public static MenuConfig GetMenuConfig(string path) { var usePath = path; MenuConfig config = new MenuConfig(); List files = new List(); #region 获取相关文件 List tempFolders = new List(); var flag = Tools.FileUtil.IsPathDirectory(path); if (flag == 1) { tempFolders.Add(usePath); } else { files.Add(usePath); } for (int i = 0; i < tempFolders.Count; i++) { var tempPath = tempFolders[i]; files.AddRange(Directory.GetFiles(tempPath)); tempFolders.AddRange(Directory.GetDirectories(tempPath)); } #endregion foreach (var file in files) { if (".dll"!= Path.GetExtension(file)?.ToLower()) { continue; } //if (!file.Contains("Tool")) //{ // continue; //} try { Assembly tempAssembly=Assembly.ReflectionOnlyLoadFrom(file); var refAssemblies = tempAssembly.GetReferencedAssemblies(); if (refAssemblies.All(s => s.Name != "FWindSoft.Revit")) { continue; } var assembly=Assembly.LoadFrom(file); var attribue = assembly.GetCustomAttribute(); if (attribue == null || !attribue.Use) { continue; } var types = assembly.GetTypes(); var interfaceName = typeof(IExternalCommand).FullName; foreach (var type in types) { if (type.GetInterface(interfaceName) != null) { if (type.IsAbstract || type.IsGenericTypeDefinition) continue; var buttonAttribute = type.GetCustomAttribute(); if (buttonAttribute == null) { continue; } #region 增加命令信息 var tab = buttonAttribute.GetTab(); if (config.Tabs.All(t => t.Name != tab.Name)) { config.Tabs.Add(tab); } var panel = buttonAttribute.GetPanel(); if (config.Panels.All(t => t.Name != panel.Name)) { config.Panels.Add(panel); } var button = buttonAttribute.GetButton(); button.AssemblyName = assembly.Location; button.ClassName = type.FullName; button.Index = buttonAttribute.Index; config.Buttons.Add(button); #endregion } } } catch (Exception ex) { //非托管dll可能会报错 } } return config; } /// /// 将assistantConfig数据合并到config中 /// /// /// /// public static MenuConfig GetMenuConfig(MenuConfig config, MenuConfig assistantConfig) { var tabs = assistantConfig.Tabs; foreach (var tab in tabs) { if (config.Tabs.Any(t => t.Name == tab.Name)) { continue; } config.Tabs.Add(tab); } var panels = assistantConfig.Panels; foreach (var panel in panels) { if (config.Panels.Any(t => t.Name == panel.Name)) { continue; } config.Panels.Add(panel); } var buttons = assistantConfig.Buttons; foreach (var button in buttons) { if (config.Buttons.Any(t => t.Name == button.Name)) { continue; } config.Buttons.Add(button); } return config; } } internal class DoaminProxy : MarshalByRefObject { public R Execute(Func func,T input) { if (func == null) { return default(R); } return func.Invoke(input); } public void Execute(Action action, T input) { if (action == null) { return ; } action(input); } internal static R NewDomainExecute(Func func, T input) { AppDomain tempAppDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString()); DoaminProxy proxy = (DoaminProxy)tempAppDomain.CreateInstanceAndUnwrap(Assembly.GetAssembly(typeof(DoaminProxy)).GetName().Name, typeof(DoaminProxy).FullName); var result = proxy.Execute(func,input); AppDomain.Unload(tempAppDomain); return result; } } }