ButtonAssemblyManager.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:ButtonAssemblyManager
  3. * 作者:xulisong
  4. * 创建时间: 2019/7/25 13:06:54
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Reflection;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using Autodesk.Revit.UI;
  15. namespace FWindSoft.Revit.Menu
  16. {
  17. public class ButtonAssemblyManager
  18. {
  19. public static MenuConfig GetMenuConfigIsolate(string path)
  20. {
  21. return DoaminProxy.NewDomainExecute(ButtonAssemblyManager.GetMenuConfig, path);
  22. }
  23. public static MenuConfig GetMenuConfig(string path)
  24. {
  25. var usePath = path;
  26. MenuConfig config = new MenuConfig();
  27. List<string> files = new List<string>();
  28. #region 获取相关文件
  29. List<string> tempFolders = new List<string>();
  30. var flag = Tools.FileUtil.IsPathDirectory(path);
  31. if (flag == 1)
  32. {
  33. tempFolders.Add(usePath);
  34. }
  35. else
  36. {
  37. files.Add(usePath);
  38. }
  39. for (int i = 0; i < tempFolders.Count; i++)
  40. {
  41. var tempPath = tempFolders[i];
  42. files.AddRange(Directory.GetFiles(tempPath));
  43. tempFolders.AddRange(Directory.GetDirectories(tempPath));
  44. }
  45. #endregion
  46. foreach (var file in files)
  47. {
  48. if (".dll"!= Path.GetExtension(file)?.ToLower())
  49. {
  50. continue;
  51. }
  52. //if (!file.Contains("Tool"))
  53. //{
  54. // continue;
  55. //}
  56. try
  57. {
  58. Assembly tempAssembly=Assembly.ReflectionOnlyLoadFrom(file);
  59. var refAssemblies = tempAssembly.GetReferencedAssemblies();
  60. if (refAssemblies.All(s => s.Name != "FWindSoft.Revit"))
  61. {
  62. continue;
  63. }
  64. var assembly=Assembly.LoadFrom(file);
  65. var attribue = assembly.GetCustomAttribute<AutoParseButtonAttribute>();
  66. if (attribue == null || !attribue.Use)
  67. {
  68. continue;
  69. }
  70. var types = assembly.GetTypes();
  71. var interfaceName = typeof(IExternalCommand).FullName;
  72. foreach (var type in types)
  73. {
  74. if (type.GetInterface(interfaceName) != null)
  75. {
  76. if (type.IsAbstract || type.IsGenericTypeDefinition)
  77. continue;
  78. var buttonAttribute = type.GetCustomAttribute<ButtonAttribute>();
  79. if (buttonAttribute == null)
  80. {
  81. continue;
  82. }
  83. #region 增加命令信息
  84. var tab = buttonAttribute.GetTab();
  85. if (config.Tabs.All(t => t.Name != tab.Name))
  86. {
  87. config.Tabs.Add(tab);
  88. }
  89. var panel = buttonAttribute.GetPanel();
  90. if (config.Panels.All(t => t.Name != panel.Name))
  91. {
  92. config.Panels.Add(panel);
  93. }
  94. var button = buttonAttribute.GetButton();
  95. button.AssemblyName = assembly.Location;
  96. button.ClassName = type.FullName;
  97. button.Index = buttonAttribute.Index;
  98. config.Buttons.Add(button);
  99. #endregion
  100. }
  101. }
  102. }
  103. catch (Exception ex)
  104. {
  105. //非托管dll可能会报错
  106. }
  107. }
  108. return config;
  109. }
  110. /// <summary>
  111. /// 将assistantConfig数据合并到config中
  112. /// </summary>
  113. /// <param name="config"></param>
  114. /// <param name="assistantConfig"></param>
  115. /// <returns></returns>
  116. public static MenuConfig GetMenuConfig(MenuConfig config, MenuConfig assistantConfig)
  117. {
  118. var tabs = assistantConfig.Tabs;
  119. foreach (var tab in tabs)
  120. {
  121. if (config.Tabs.Any(t => t.Name == tab.Name))
  122. {
  123. continue;
  124. }
  125. config.Tabs.Add(tab);
  126. }
  127. var panels = assistantConfig.Panels;
  128. foreach (var panel in panels)
  129. {
  130. if (config.Panels.Any(t => t.Name == panel.Name))
  131. {
  132. continue;
  133. }
  134. config.Panels.Add(panel);
  135. }
  136. var buttons = assistantConfig.Buttons;
  137. foreach (var button in buttons)
  138. {
  139. if (config.Buttons.Any(t => t.Name == button.Name))
  140. {
  141. continue;
  142. }
  143. config.Buttons.Add(button);
  144. }
  145. return config;
  146. }
  147. }
  148. internal class DoaminProxy : MarshalByRefObject
  149. {
  150. public R Execute<T, R>(Func<T, R> func,T input)
  151. {
  152. if (func == null)
  153. {
  154. return default(R);
  155. }
  156. return func.Invoke(input);
  157. }
  158. public void Execute<T>(Action<T> action, T input)
  159. {
  160. if (action == null)
  161. {
  162. return ;
  163. }
  164. action(input);
  165. }
  166. internal static R NewDomainExecute<T, R>(Func<T, R> func, T input)
  167. {
  168. AppDomain tempAppDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
  169. DoaminProxy proxy = (DoaminProxy)tempAppDomain.CreateInstanceAndUnwrap(Assembly.GetAssembly(typeof(DoaminProxy)).GetName().Name, typeof(DoaminProxy).FullName);
  170. var result = proxy.Execute<T,R>(func,input);
  171. AppDomain.Unload(tempAppDomain);
  172. return result;
  173. }
  174. }
  175. }