瀏覽代碼

mxg:创建ServiceMBI项目

mengxiangge 6 年之前
當前提交
f092b28dd1
共有 59 個文件被更改,包括 5123 次插入0 次删除
  1. 5 0
      .gitignore
  2. 二進制
      Dlls/R2016/AdWindows.dll
  3. 二進制
      Dlls/R2016/RevitAPI.dll
  4. 二進制
      Dlls/R2016/RevitAPIIFC.dll
  5. 二進制
      Dlls/R2016/RevitAPILink.dll
  6. 二進制
      Dlls/R2016/RevitAPIUI.dll
  7. 二進制
      Dlls/R2016/RevitAPIUILink.dll
  8. 二進制
      Dlls/R2017/AdWindows.dll
  9. 二進制
      Dlls/R2017/RevitAPI.dll
  10. 二進制
      Dlls/R2017/RevitAPIIFC.dll
  11. 二進制
      Dlls/R2017/RevitAPILink.dll
  12. 二進制
      Dlls/R2017/RevitAPIUI.dll
  13. 二進制
      Dlls/R2017/RevitAPIUILink.dll
  14. 二進制
      Dlls/R2018/RevitAPI.dll
  15. 二進制
      Dlls/R2018/RevitAPIUI.dll
  16. 二進制
      Dlls/RevitRefDll/AdWindows.dll
  17. 二進制
      Dlls/RevitRefDll/RevitAPI.dll
  18. 二進制
      Dlls/RevitRefDll/RevitAPIIFC.dll
  19. 二進制
      Dlls/RevitRefDll/RevitAPILink.dll
  20. 二進制
      Dlls/RevitRefDll/RevitAPIUI.dll
  21. 二進制
      Dlls/RevitRefDll/RevitAPIUILink.dll
  22. 二進制
      Dlls/RevitRefDll/RevitAddInUtility.dll
  23. 二進制
      Dlls/SAGA.DotNetUtils.dll
  24. 二進制
      Dlls/SAGA.RevitUtils.dll
  25. 44 0
      SAGA.RevitMenu/Addin/RevitProductExt.cs
  26. 294 0
      SAGA.RevitMenu/Addin/RevitStartHelper.cs
  27. 23 0
      SAGA.RevitMenu/Addin/RevitVersionExt.cs
  28. 234 0
      SAGA.RevitMenu/ChangeProduct.cs
  29. 21 0
      SAGA.RevitMenu/ChangeProductCmd.cs
  30. 14 0
      SAGA.RevitMenu/Configuration/ButtonStyles.cs
  31. 96 0
      SAGA.RevitMenu/Configuration/MenuConfig.cs
  32. 271 0
      SAGA.RevitMenu/Configuration/RevitRibbonOperate.cs
  33. 18 0
      SAGA.RevitMenu/Configuration/RevitVer.cs
  34. 11 0
      SAGA.RevitMenu/Configuration/StackStyles.cs
  35. 57 0
      SAGA.RevitMenu/Configuration/TszButtonData.cs
  36. 143 0
      SAGA.RevitMenu/Configuration/TszPanelData.cs
  37. 86 0
      SAGA.RevitMenu/Configuration/TszTabData.cs
  38. 359 0
      SAGA.RevitMenu/Configuration/XmlMenuData.cs
  39. 67 0
      SAGA.RevitMenu/Configuration/XmlMenuDataWrapper.cs
  40. 187 0
      SAGA.RevitMenu/Globals.cs
  41. 171 0
      SAGA.RevitMenu/MenuApp.cs
  42. 36 0
      SAGA.RevitMenu/Properties/AssemblyInfo.cs
  43. 214 0
      SAGA.RevitMenu/SAGA.RevitMenu.csproj
  44. 6 0
      SAGA.RevitMenu/SAGA.RevitMenu.csproj.user
  45. 217 0
      SAGA.RevitMenu/ScreenMenu.cs
  46. 27 0
      SAGA.RevitMenu/SetMenuCmd.cs
  47. 552 0
      SAGA.RevitMenu/SetMenuForm.cs
  48. 37 0
      SAGA.RevitMenu/Setting/StartSetting.cs
  49. 1473 0
      SAGA.RevitMenu/ShortKey/KeyboardShortcuts.xml
  50. 97 0
      SAGA.RevitMenu/ShortKey/ScreenMenuKeyBoardShortCut.cs
  51. 41 0
      SAGA.RevitMenu/ShortKey/ShortKeyHelper.cs
  52. 26 0
      SAGA.RevitMenu/TSZHideScreenMenuCmd.cs
  53. 24 0
      SAGA.RevitMenu/TSZShowScreenMenuCmd.cs
  54. 96 0
      ServiceMBI.sln
  55. 6 0
      ServiceMBI/App.config
  56. 51 0
      ServiceMBI/Command.cs
  57. 15 0
      ServiceMBI/Program.cs
  58. 36 0
      ServiceMBI/Properties/AssemblyInfo.cs
  59. 68 0
      ServiceMBI/ServiceMBI.csproj

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+################################################################################
+# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
+################################################################################
+
+/SAGA.RevitMenu/obj

二進制
Dlls/R2016/AdWindows.dll


二進制
Dlls/R2016/RevitAPI.dll


二進制
Dlls/R2016/RevitAPIIFC.dll


二進制
Dlls/R2016/RevitAPILink.dll


二進制
Dlls/R2016/RevitAPIUI.dll


二進制
Dlls/R2016/RevitAPIUILink.dll


二進制
Dlls/R2017/AdWindows.dll


二進制
Dlls/R2017/RevitAPI.dll


二進制
Dlls/R2017/RevitAPIIFC.dll


二進制
Dlls/R2017/RevitAPILink.dll


二進制
Dlls/R2017/RevitAPIUI.dll


二進制
Dlls/R2017/RevitAPIUILink.dll


二進制
Dlls/R2018/RevitAPI.dll


二進制
Dlls/R2018/RevitAPIUI.dll


二進制
Dlls/RevitRefDll/AdWindows.dll


二進制
Dlls/RevitRefDll/RevitAPI.dll


二進制
Dlls/RevitRefDll/RevitAPIIFC.dll


二進制
Dlls/RevitRefDll/RevitAPILink.dll


二進制
Dlls/RevitRefDll/RevitAPIUI.dll


二進制
Dlls/RevitRefDll/RevitAPIUILink.dll


二進制
Dlls/RevitRefDll/RevitAddInUtility.dll


二進制
Dlls/SAGA.DotNetUtils.dll


二進制
Dlls/SAGA.RevitUtils.dll


+ 44 - 0
SAGA.RevitMenu/Addin/RevitProductExt.cs

@@ -0,0 +1,44 @@
+
+/* ==============================================================================
+ * 功能描述:Revit 版本信息 对RevitProduct进行一次包装
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/9/17 
+ * ==============================================================================*/
+
+using System.IO;
+using Autodesk.RevitAddIns;
+
+namespace SAGA.RevitUtility
+{
+    public class RevitProductExt
+    {
+        public RevitProductExt(RevitProduct rp)
+        {
+            this.Name = rp.Name;
+            this.InstallLocation = rp.InstallLocation;
+            this.RevitExeFile = Path.Combine(this.InstallLocation, "Revit.exe");
+            this.CurrentUserAddInFolder = rp.CurrentUserAddInFolder;
+            this.AllUsersAddInFolder = rp.AllUsersAddInFolder;
+            this.Version = rp.Version.ToString();
+        }
+        /// <summary>
+        /// 公用 用户的文件夹路径
+        /// </summary>
+        public string AllUsersAddInFolder { get; set; }
+        /// <summary>
+        /// 当前用户的文件夹路径
+        /// </summary>
+        public string CurrentUserAddInFolder { get; set; }
+        /// <summary>
+        /// Revit 安装路径
+        /// </summary>
+        public string InstallLocation { get; set; }
+
+        public string Name { get; set; }
+
+        public string RevitExeFile { get; set; }
+
+        public string Version { get; set; }
+    }
+}
+

+ 294 - 0
SAGA.RevitMenu/Addin/RevitStartHelper.cs

@@ -0,0 +1,294 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using Autodesk.RevitAddIns;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Others;
+
+namespace SAGA.RevitUtility
+{
+    public static class RevitStartHelper
+    {
+        private const string AddInFormat = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RevitAddIns>\r\n<AddIn Type=\"Application\">\r\n<Name>{0}</Name>\r\n<Assembly>{1}</Assembly>\r\n<AddInId>{2}</AddInId>\r\n<FullClassName>{3}</FullClassName>\r\n<VendorId>{4}</VendorId>\r\n<VendorDescription>上格云技术, www.sagacloud.cn</VendorDescription>\r\n</AddIn>\r\n</RevitAddIns>";
+        /// <summary>
+        /// 启动完成后删除Addin文件
+        /// </summary>
+        /// <param name="addInId"></param>
+        /// <param name="strProductType"></param>
+        /// <param name="strRevitVersion"></param>
+        /// <returns></returns>
+        public static bool ClearAddInFile(Guid addInId, string strProductType, string strRevitVersion)
+        {
+            try
+            {
+                RevitVersionExt ext;
+                ProductType unknown = ProductType.Unknown;
+                string str7 = strProductType;
+                if (str7 != null)
+                {
+                    if (!(str7 == "Revit"))
+                    {
+                        if (str7 == "Architecture")
+                        {
+                            goto Label_0054;
+                        }
+                        if (str7 == "Structure")
+                        {
+                            goto Label_0058;
+                        }
+                        if (str7 == "MEP")
+                        {
+                            goto Label_005C;
+                        }
+                        if (str7 == "Unknown")
+                        {
+                            goto Label_0060;
+                        }
+                    }
+                    else
+                    {
+                        unknown = ProductType.Revit;
+                    }
+                }
+                goto Label_0062;
+            Label_0054:
+                unknown = ProductType.Architecture;
+                goto Label_0062;
+            Label_0058:
+                unknown = ProductType.Structure;
+                goto Label_0062;
+            Label_005C:
+                unknown = ProductType.MEP;
+                goto Label_0062;
+            Label_0060:
+                unknown = ProductType.Unknown;
+            Label_0062:
+                ext = GetRevitVersion(strRevitVersion);
+                if ((unknown == ProductType.Unknown) || (ext == RevitVersionExt.Unknown))
+                {
+                    return false;
+                }
+                //获取所有安装过的Revit版本
+                List<RevitProduct> allInstalledRevitProducts = RevitProductUtility.GetAllInstalledRevitProducts();
+                if ((allInstalledRevitProducts == null) || (allInstalledRevitProducts.Count <= 0))
+                {
+                    return false;
+                }
+                RevitProduct product = null;
+                foreach (RevitProduct product2 in allInstalledRevitProducts)
+                {
+                    if ((product2.Product == unknown) && (product2.Version == ((RevitVersion) ((int) ext))))
+                    {
+                        product = product2;
+                        break;
+                    }
+                }
+                if (product != null)
+                {
+                    string currentUserAddInFolder = product.CurrentUserAddInFolder;
+                    string allUsersAddInFolder = product.AllUsersAddInFolder;
+                    string str4 = GetTszPoductString(addInId.ToString()) + ".addin";
+                    string[] strArray = new string[] { currentUserAddInFolder, allUsersAddInFolder };
+                    foreach (string str5 in strArray)
+                    {
+                        if ((str5 != null) && (str5.Trim().Length > 0))
+                        {
+                            string path = Path.Combine(str5, str4);
+                            if (File.Exists(path))
+                            {
+                                try
+                                {
+                                    File.Delete(path);
+                                }
+                                catch
+                                {
+                                }
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+        }
+        /// <summary>
+        /// AddIn内部文件赋值
+        /// </summary>
+        /// <param name="strFormat"></param>
+        /// <param name="strAddInId"></param>
+        /// <returns></returns>
+        public static string GetAddInFormatString(string strFormat, string strAddInId)
+        {
+            string str = "上格云技术";
+            string str2 = "SAGA.RevitMenu.MenuApp";
+            string str3 = "SAGA";
+            string revitMenuDll = GetRevitMenuDll();
+            return string.Format(strFormat, new object[] { str, revitMenuDll, strAddInId, str2, str3 });
+        }
+        /// <summary>
+        /// 获取Revit启动加载dll的路径
+        /// </summary>
+        /// <returns></returns>
+        public static string GetRevitMenuDll()
+        {
+            return Path.Combine(Path.Combine(AppBaseInfo.AppRunPath, "OutputDll"), "SAGA.RevitMenu.dll");
+        }
+        /// <summary>
+        /// 获取已安装的Revit版本信息
+        /// </summary>
+        /// <returns></returns>
+        public static List<RevitProductExt> GetRevitProductExts()
+        {
+            List<RevitProductExt> list = new List<RevitProductExt>();
+            foreach (RevitProduct product in RevitProductUtility.GetAllInstalledRevitProducts())
+            {
+                list.Add(new RevitProductExt(product));
+            }
+            return list;
+        }
+        
+        /// <summary>
+        /// 当前Dll支持的Revit版本
+        /// </summary>
+        /// <param name="revitVer"></param>
+        /// <returns></returns>
+        public static RevitProductExt GetRevitProductExt(RevitVersionExt revitVer)
+        {
+            return GetRevitProductExt(revitVer.ToString());
+        }
+
+        /// <summary>
+        /// 当前Dll支持的Revit版本
+        /// </summary>
+        /// <param name="strRevitVer"></param>
+        /// <returns></returns>
+        public static RevitProductExt GetRevitProductExt(string strRevitVer)
+        {
+            RevitProductExt objRtn = null;
+            var rproducts = GetRevitProductExts();
+
+            var filterProducts = rproducts.Where(rproduct => rproduct.Version == strRevitVer).ToList();
+
+            if (filterProducts.IsNotNullEmptyExt())
+            {
+                objRtn = filterProducts[0];
+            }
+            return objRtn;
+        }
+        /// <summary>
+        /// 2018 转化为RevitVersionExt.Revit2018
+        /// </summary>
+        /// <param name="strVersionNumber"></param>
+        /// <returns></returns>
+        public static RevitVersionExt GetRevitVersion(string strVersionNumber)
+        {
+            RevitVersionExt result = RevitVersionExt.Unknown;
+
+            if (strVersionNumber == null)
+            {
+                return result;
+            }
+            string str = strVersionNumber;
+            int versionInt = str.ToInt();
+            int rvInt = versionInt - 2010;
+            try
+            {
+                result = (RevitVersionExt) rvInt;
+            }
+            catch 
+            {
+                //强转失败
+                result=RevitVersionExt.Unknown;
+            }
+            return result;
+        }
+        /// <summary>
+        /// 获取AddIn文件的名称
+        /// </summary>
+        /// <param name="strAddInId"></param>
+        /// <returns></returns>
+        public static string GetTszPoductString(string strAddInId)
+        {
+            string str2;
+            string str = "";
+            //if (((str2 = strAddInId.ToUpper()) != null) && (str2 == "EABBE53F-04A0-4D10-905F-FE4DB67E1F3C"))
+            //{
+            //    str = "TSBIM";
+            //}
+            str = "SAGABIM";
+            return str;
+        }
+
+        [DllImport("shell32.dll")]
+        public static extern int ShellExecute(IntPtr hwnd, StringBuilder lpszOp, StringBuilder lpszFile, StringBuilder lpszParams, StringBuilder lpszDir, int fsShowCmd);
+        public static bool StartRevit(RevitProductExt prodInfo, List<string> listTszProg)
+        {
+            try
+            {
+                string currentUserAddInFolder = prodInfo.CurrentUserAddInFolder;
+                string allUsersAddInFolder = prodInfo.AllUsersAddInFolder;
+                string[] strArray = new string[] { currentUserAddInFolder };
+                //foreach (string str3 in listTszProg)
+                {
+                    string str3 = "EABBE53F-04A0-4D10-905F-FE4DB67E1F3C";//addinid,后期可根据需要修改
+                    string str5 = GetTszPoductString(str3) + ".addin";
+                    foreach (string str6 in strArray)
+                    {
+                        if ((str6 != null) && (str6.Trim().Length > 0))
+                        {
+                            string path = Path.Combine(str6, str5);
+                            string str8 = Path.Combine(allUsersAddInFolder, str5);
+                            try
+                            {
+                                if (!Directory.Exists(str6))
+                                {
+                                    Directory.CreateDirectory(str6);
+                                }
+                                if (File.Exists(path))
+                                {
+                                    File.Delete(path);
+                                }
+                                if (File.Exists(str8))
+                                {
+                                    File.Delete(str8);
+                                }
+                            }
+                            catch
+                            {
+                            }
+                            using (StreamWriter writer = new StreamWriter(path, false, Encoding.UTF8))
+                            {
+                                string addInFormatString = GetAddInFormatString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RevitAddIns>\r\n<AddIn Type=\"Application\">\r\n<Name>{0}</Name>\r\n<Assembly>{1}</Assembly>\r\n<AddInId>{2}</AddInId>\r\n<FullClassName>{3}</FullClassName>\r\n<VendorId>{4}</VendorId>\r\n<VendorDescription>上格云技术, www.sagacloud.cn</VendorDescription>\r\n</AddIn>\r\n</RevitAddIns>", str3);
+                                if (!string.IsNullOrEmpty(addInFormatString))
+                                {
+                                    writer.Write(addInFormatString);
+                                }
+                                else
+                                {
+                                    MessageShowBase.Infomation("初始化Revit加载信息错误");
+                                    return false;
+                                }
+                            }
+                        }
+                    }
+                }
+                string directoryName = Path.GetDirectoryName(prodInfo.RevitExeFile);
+                return (ShellExecute(IntPtr.Zero, new StringBuilder("open"), new StringBuilder("Revit"), new StringBuilder(""), new StringBuilder(directoryName), 1) > 0x20);
+            }
+            catch (Exception exception)
+            {
+                MessageShowBase.Infomation("配置Revit加载文件失败,请以管理员登录或在控制面板中“更改UAC设置”。");
+                MessageShowBase.Show(exception);
+                return false;
+            }
+        }
+    }
+}
+

+ 23 - 0
SAGA.RevitMenu/Addin/RevitVersionExt.cs

@@ -0,0 +1,23 @@
+
+/* ==============================================================================
+ * 功能描述:Revit 版本的枚举
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/9/17 
+ * ==============================================================================*/
+
+namespace SAGA.RevitUtility
+{
+    public enum RevitVersionExt
+    {
+        Revit2011 = 1,
+        Revit2012 = 2,
+        Revit2013 = 3,
+        Revit2014 = 4,
+        Revit2015 = 5,
+        Revit2016 = 6,
+        Revit2017 = 7,
+        Revit2018 = 8,
+        Unknown = -1
+    }
+}
+

+ 234 - 0
SAGA.RevitMenu/ChangeProduct.cs

@@ -0,0 +1,234 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Windows.Forms;
+using Microsoft.Win32;
+using SAGY.DotNetUtils;
+using SAGY.DotNetUtils.Configration;
+using SAGY.DotNetUtils.WinForms;
+using SAGY.RevitUtility;
+
+namespace SAGY.RevitMenu
+{
+    public class ChangeProduct : BaseForm
+    {
+        private static Dictionary<string, string> _mConfigParam;
+        private static Dictionary<string, string> _mConfigProduct;
+        private Button btn_Cancle;
+        private Button btn_OK;
+        private IContainer components;
+        private DataGridView dataGridView1;
+        private GroupBox groupBox1;
+        private DataGridViewTextBoxColumn ParamName;
+        private DataGridViewTextBoxColumn Path;
+        private DataGridViewTextBoxColumn ProName;
+        private DataGridViewTextBoxColumn Ver;
+
+        public ChangeProduct()
+        {
+            this.InitializeComponent();
+        }
+
+        private void btn_Cancle_Click(object sender, EventArgs e)
+        {
+            base.Close();
+        }
+
+        private void btn_OK_Click(object sender, EventArgs e)
+        {
+            if ((this.dataGridView1.CurrentRow != null) && (this.dataGridView1.CurrentRow.Index != -1))
+            {
+                string str = this.dataGridView1.Rows[this.dataGridView1.CurrentRow.Index].Cells["Path"].Value.ToString();
+                string str2 = this.dataGridView1.Rows[this.dataGridView1.CurrentRow.Index].Cells["ParamName"].Value.ToString();
+                Process process = new Process();
+                string fileName = str + @"DLL\TSZ.Revit.exe";
+                string str4 = RevitStartHelper.GetRevitProductVer1(VersionAdapter.RevitApiVersion);
+                ProcessStartInfo info = new ProcessStartInfo(fileName, str4 + " " + str2);
+                process.StartInfo = info;
+                process.Start();
+            }
+            base.Close();
+        }
+
+        private void ChangeProduct_Load(object sender, EventArgs e)
+        {
+            string path = AppBaseInfo.AppRunPath + @"\DLL\TSZ.Revit.exe";
+            if (File.Exists(path))
+            {
+                FileInfo info = new FileInfo(path);
+                this.Text = "当前程序版本:" + info.LastWriteTime.ToString("yyyy-MM-dd");
+            }
+            foreach (string str2 in Registry.LocalMachine.OpenSubKey(@"SOFTWARE\TszCAD").GetSubKeyNames())
+            {
+                string str3;
+                RegistryKey key2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\TszCAD\" + str2);
+                if ((key2 != null) && ConfigProduct.TryGetValue(str2.Substring(str2.LastIndexOf("-", StringComparison.Ordinal) + 1), out str3))
+                {
+                    string str4 = key2.GetValue("Path").ToString();
+                    string str5 = str4 + @"DLL\TSZ.Revit.exe";
+                    if (File.Exists(str5))
+                    {
+                        FileInfo info2 = new FileInfo(str5);
+                        string str6 = info2.LastWriteTime.ToString("yyyy-MM-dd");
+                        this.dataGridView1.Rows.Add(1);
+                        int num = this.dataGridView1.Rows.Count - 1;
+                        string str7 = str2.Split(new char[] { '-' })[0];
+                        this.dataGridView1.Rows[num].Cells["Ver"].Value = str7.Substring(str7.Length - 4) + "(" + str6 + ")";
+                        ProductEnum featuresBit = (ProductEnum) Enum.Parse(typeof(ProductEnum), str3);
+                        this.dataGridView1.Rows[num].Cells["ProName"].Value = ProductUtil.GetModuleName(featuresBit);
+                        ConfigParam.TryGetValue(str2.Substring(str2.LastIndexOf("-", StringComparison.Ordinal) + 1), out str3);
+                        this.dataGridView1.Rows[num].Cells["ParamName"].Value = str3;
+                        this.dataGridView1.Rows[num].Cells["Path"].Value = str4;
+                    }
+                }
+            }
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (this.components != null))
+            {
+                this.components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        private void InitializeComponent()
+        {
+            ComponentResourceManager manager = new ComponentResourceManager(typeof(ChangeProduct));
+            this.btn_Cancle = new Button();
+            this.btn_OK = new Button();
+            this.groupBox1 = new GroupBox();
+            this.dataGridView1 = new DataGridView();
+            this.Ver = new DataGridViewTextBoxColumn();
+            this.ProName = new DataGridViewTextBoxColumn();
+            this.ParamName = new DataGridViewTextBoxColumn();
+            this.Path = new DataGridViewTextBoxColumn();
+            this.groupBox1.SuspendLayout();
+            ((ISupportInitialize) this.dataGridView1).BeginInit();
+            base.SuspendLayout();
+            this.btn_Cancle.Location = new Point(0xe4, 0x128);
+            this.btn_Cancle.Name = "btn_Cancle";
+            this.btn_Cancle.Size = new Size(0x4b, 0x17);
+            this.btn_Cancle.TabIndex = 5;
+            this.btn_Cancle.Text = "关闭";
+            this.btn_Cancle.UseVisualStyleBackColor = true;
+            this.btn_Cancle.Click += new EventHandler(this.btn_Cancle_Click);
+            this.btn_OK.Location = new Point(0x93, 0x128);
+            this.btn_OK.Name = "btn_OK";
+            this.btn_OK.Size = new Size(0x4b, 0x17);
+            this.btn_OK.TabIndex = 4;
+            this.btn_OK.Text = "启动";
+            this.btn_OK.UseVisualStyleBackColor = true;
+            this.btn_OK.Click += new EventHandler(this.btn_OK_Click);
+            this.groupBox1.Controls.Add(this.dataGridView1);
+            this.groupBox1.Location = new Point(11, 15);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new Size(0x12a, 0x113);
+            this.groupBox1.TabIndex = 3;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "已安装产品";
+            this.dataGridView1.AllowUserToAddRows = false;
+            this.dataGridView1.BackgroundColor = System.Drawing.Color.White;
+            this.dataGridView1.BorderStyle = BorderStyle.Fixed3D;
+            this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.dataGridView1.Columns.AddRange(new DataGridViewColumn[] { this.Ver, this.ProName, this.ParamName, this.Path });
+            this.dataGridView1.GridColor = System.Drawing.Color.White;
+            this.dataGridView1.Location = new Point(6, 20);
+            this.dataGridView1.MultiSelect = false;
+            this.dataGridView1.Name = "dataGridView1";
+            this.dataGridView1.ReadOnly = true;
+            this.dataGridView1.RowHeadersVisible = false;
+            this.dataGridView1.RowTemplate.Height = 0x17;
+            this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
+            this.dataGridView1.Size = new Size(0x11e, 0xf9);
+            this.dataGridView1.TabIndex = 0;
+            this.Ver.DataPropertyName = "Ver";
+            this.Ver.HeaderText = "版本";
+            this.Ver.Name = "Ver";
+            this.Ver.ReadOnly = true;
+            this.Ver.Width = 120;
+            this.ProName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
+            this.ProName.DataPropertyName = "ProName";
+            this.ProName.HeaderText = "名称";
+            this.ProName.Name = "ProName";
+            this.ProName.ReadOnly = true;
+            this.ParamName.DataPropertyName = "ParamName";
+            this.ParamName.HeaderText = "ParamName";
+            this.ParamName.Name = "ParamName";
+            this.ParamName.ReadOnly = true;
+            this.ParamName.Visible = false;
+            this.Path.DataPropertyName = "Path";
+            this.Path.HeaderText = "路径";
+            this.Path.Name = "Path";
+            this.Path.ReadOnly = true;
+            this.Path.Visible = false;
+            base.AutoScaleDimensions = new SizeF(6f, 12f);
+            base.ClientSize = new Size(0x141, 0x14c);
+            base.Controls.Add(this.btn_Cancle);
+            base.Controls.Add(this.btn_OK);
+            base.Controls.Add(this.groupBox1);
+            base.MaximizeBox = false;
+            base.MinimizeBox = false;
+            base.Name = "ChangeProduct";
+            base.StartPosition = FormStartPosition.CenterScreen;
+            this.Text = "产品切换";
+            base.Load += new EventHandler(this.ChangeProduct_Load);
+            this.groupBox1.ResumeLayout(false);
+            ((ISupportInitialize) this.dataGridView1).EndInit();
+            base.ResumeLayout(false);
+        }
+
+        public static Dictionary<string, string> ConfigParam
+        {
+            get
+            {
+                Dictionary<string, string> dictionary;
+                if (_mConfigParam == null)
+                {
+                    dictionary = new Dictionary<string, string>();
+                    dictionary.Add("TSRA", "TSRA");
+                    dictionary.Add("TSRS", "TSRS");
+                    dictionary.Add("TSPT", "TSPT");
+                    dictionary.Add("T3PT", "T3PT");
+                    dictionary.Add("TS3DSR", "TS3DSR");
+                    dictionary.Add("TSCC", "TSCC");
+                    dictionary.Add("TSCF", "TSCF");
+                    dictionary.Add("TSDCP", "TSDCP");
+                    dictionary.Add("TSRFA", "TSRFA");
+                    dictionary.Add("TSRMEP", "TSRMEP");
+                    dictionary.Add("地下特种结构", "TSIPS");
+                }
+                return (_mConfigParam = dictionary);
+            }
+        }
+
+        public static Dictionary<string, string> ConfigProduct
+        {
+            get
+            {
+                Dictionary<string, string> dictionary;
+                if (_mConfigProduct == null)
+                {
+                    dictionary = new Dictionary<string, string>();
+                    dictionary.Add("TSRA", "TSRA");
+                    dictionary.Add("TSRS", "TSRS");
+                    dictionary.Add("TSPT", "TSPTREVIT");
+                    dictionary.Add("T3PT", "T3PTREVIT");
+                    dictionary.Add("TS3DSR", "TS3DSR");
+                    dictionary.Add("TSCC", "TSCC");
+                    dictionary.Add("TSCF", "TSCF");
+                    dictionary.Add("TSDCP", "TSDCP");
+                    dictionary.Add("TSRFA", "TSRFA");
+                    dictionary.Add("TSRMEP", "TSRMEP");
+                    dictionary.Add("地下特种结构", "TSIPS");
+                }
+                return (_mConfigProduct = dictionary);
+            }
+        }
+    }
+}
+

+ 21 - 0
SAGA.RevitMenu/ChangeProductCmd.cs

@@ -0,0 +1,21 @@
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+
+namespace SAGY.RevitMenu
+{
+    [Transaction(TransactionMode.Manual), Regeneration(RegenerationOption.Manual)]
+    public class ChangeProductCmd : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
+            {
+                return Result.Cancelled;
+            }
+            new ChangeProduct().ShowDialog(base.WinImpl);
+            return Result.Succeeded;
+        }
+    }
+}
+

+ 14 - 0
SAGA.RevitMenu/Configuration/ButtonStyles.cs

@@ -0,0 +1,14 @@
+namespace TSZ.RevitMenu.Configuration
+{
+    using System;
+
+    public enum ButtonStyles
+    {
+        Separator,
+        Large,
+        Pushdown,
+        Stacked,
+        StackedBox
+    }
+}
+

+ 96 - 0
SAGA.RevitMenu/Configuration/MenuConfig.cs

@@ -0,0 +1,96 @@
+
+/* ==============================================================================
+ * 功能描述:启动Revit时自定义菜单配置
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/8/30 
+ * ==============================================================================*/
+
+using Autodesk.Revit.UI;
+using SAGA.DotNetUtils;
+using SAGA.RevitUtils;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows.Media.Imaging;
+using System.Xml;
+using Autodesk.Windows;
+using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Others;
+using TSZ.RevitMenu.Configuration;
+using SAGA.RevitUtility;
+using RibbonItem = Autodesk.Revit.UI.RibbonItem;
+using RibbonPanel = Autodesk.Revit.UI.RibbonPanel;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    public class MenuConfig
+    {
+        /// <summary>
+        /// 加载菜单
+        /// </summary>
+        /// <param name="application"></param>
+        /// <returns></returns>
+        public static bool LoadMenus(UIControlledApplication application)
+        {
+            try
+            {
+                if (application.ActiveAddInId == null)
+                {
+                    return false;
+                }
+                Guid gUID = application.ActiveAddInId.GetGUID();
+                string str = "";
+                if (gUID.ToString().ToUpper() == "EABBE53F-04A0-4D10-905F-FE4DB67E1F3C")
+                {
+                    str = "TSBIM";
+                }
+                if (str.Length == 0)
+                {
+                    return false;
+                }
+                bool blnRevit = false;
+                TszTabData[] configTabs = XmlMenuData.GetConfigTabs(application.ControlledApplication.VersionNumber, out blnRevit);
+                if ((configTabs == null) || (configTabs.Length <= 0))
+                {
+                    MessageShow.Infomation("菜单加载错误:菜单配置文件异常");
+                    return false;
+                }
+                //跟据权限对数据进行修饰
+                //XmlMenuDataWrapper.Wrapper(configTabs);
+                bool flag2 = RevitRibbonOperate.ApplyConfigTabs(application, configTabs);
+                return flag2;
+            }
+            catch (Exception exception)
+            {
+                if (exception.Message == "Too many tabs have been created by the API. Instead, you may add your Ribbon Panels to the Add-Ins tab.")
+                {
+                    MessageShow.Infomation("启动的插件菜单过多,请勿全部勾选或卸载其它插件。");
+                }
+                else
+                {
+                    MessageShow.Show(exception, false, "");
+                }
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 清除Addins文件
+        /// </summary>
+        /// <param name="application"></param>
+        /// <returns></returns>
+        public static bool ClearAddInFile(UIControlledApplication application)
+        {
+            if (application.ActiveAddInId == null)
+            {
+                return false;
+            }
+            Guid guid = application.ActiveAddInId.GetGUID();
+            string strProductType = application.ControlledApplication.Product.ToString();
+            string versionNumber = application.ControlledApplication.VersionNumber;
+            return RevitStartHelper.ClearAddInFile(guid, strProductType, versionNumber);
+        }
+    }
+}
+

+ 271 - 0
SAGA.RevitMenu/Configuration/RevitRibbonOperate.cs

@@ -0,0 +1,271 @@
+/* ==============================================================================
+ * 功能描述:RevitRibbon生成操作
+ * 创 建 者:Garrett
+ * 创建日期:2018/9/17 18:01:44
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+using Autodesk.Revit.UI;
+using Autodesk.Windows;
+using SAGA.RevitUtils;
+using TSZ.RevitMenu.Configuration;
+using RibbonItem = Autodesk.Revit.UI.RibbonItem;
+using RibbonPanel = Autodesk.Revit.UI.RibbonPanel;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    /// <summary>
+    /// RevitRibbonOperate
+    /// </summary>
+    class RevitRibbonOperate
+    {
+        /// <summary>
+        /// 创建菜单 
+        /// </summary>
+        /// <param name="app"></param>
+        /// <param name="configTabs"></param>
+        /// <returns></returns>
+        public static bool ApplyConfigTabs(UIControlledApplication app, TszTabData[] configTabs)
+        {
+            int index = 0;
+
+            if (!AddSignToTab(configTabs))
+                return false;
+            for (int j = 0; j < configTabs.Length; j++)
+            {
+                if (j == 18)
+                {
+                    //经测试,最多为20个,为保险暂保留15个。
+                    MessageShow.Infomation("菜单Tab页签项过多,只加载了18个Tab页签。");
+                    break;
+                }
+
+                #region 创建RibbonTab 前后加【】
+
+                TszTabData tabData = configTabs[j];
+                //没有可用button不创建
+                if (!tabData.HasVisibleItem())
+                    continue;
+                List<RibbonPanel> listRibPanel;
+                try
+                {//获取自定义Tab下的Panel,如果Tab不存在,抛出异常
+                    listRibPanel = app.GetRibbonPanels(tabData.TabName);
+                }
+                catch (Exception e)
+                {
+                    app.CreateRibbonTab(tabData.TabName);
+                    listRibPanel = new List<RibbonPanel>();
+                }
+
+                #endregion
+
+
+                foreach (TszPanelData panelData in tabData.Panels)
+                {
+                    #region 创建RibbonPanel
+
+                    bool blnExist = panelData.ValidateData();
+                    if (!blnExist||!panelData.HasVisibleItem())
+                    {
+                        continue;
+                    }
+
+                    var rvtRibbonPanel = listRibPanel.Find(p => p.Name == panelData.PanelName);
+
+                    List<RibbonItem> listPanelItem = new List<RibbonItem>();
+                    if (rvtRibbonPanel == null)
+                    {
+                        rvtRibbonPanel = app.CreateRibbonPanel(tabData.TabName, panelData.PanelName);
+                        rvtRibbonPanel.Visible = panelData.Visible;
+                    }
+                    else
+                    {
+                        listPanelItem = rvtRibbonPanel.GetItems().ToList();
+                    }
+
+                    #endregion
+                    //分割符数据
+                    RibbonItem separatorBeforeVisibleItem = null;//分割符之前的可见Button
+                    bool separatorStandBy = false;//准备放置分割符
+                    Action<RibbonItem, bool> setRibbonItemVisibleAction = (t, b) =>
+                    {
+                        t.Visible = b;
+                        if (b)
+                            separatorBeforeVisibleItem = t;
+                    };
+
+                    PulldownButton pulldownButton = null;
+                    List<Tuple<ButtonData, bool>> stackButtonDatas = new List<Tuple<ButtonData, bool>>();
+                    IList<RibbonItem> ribbonItems = null;
+                    for (int i = 0; i < panelData.Buttons.Count; i++)
+                    {
+                        bool isLast = false;
+
+                        #region 按钮
+
+                        TszButtonData tszbuttonData = panelData.Buttons[i];
+                        tszbuttonData.ButtonText = tszbuttonData.ButtonText?.Replace(" ", Environment.NewLine);
+
+                        //不加载名为NEWTEXTBUTTON的按钮(该按钮在Panel为空时仅为找TabName用,自行在XML中添加) wxy 2017-4-18
+                        if (tszbuttonData.ButtonText == "NEWTEXTBUTTON")
+                            continue;
+                        //RibbonPalel中不允许同名Button
+                        if (listPanelItem.Exists(p => p.Name == tszbuttonData.ButtonName))
+                        {
+                            continue;
+                        }
+
+                        PushButtonData pushbuttonData = null;
+                        PushButton pushButton = null;
+                        //加载Stack排列类型的命令
+                        #region 添加Stack Button
+                        PlaceStackStart:
+                        if (stackButtonDatas.Count > 0 && tszbuttonData.Styles != ButtonStyles.Stacked || isLast)
+                        {
+                            if (stackButtonDatas.Count >= 3)
+                            {
+                                ribbonItems = rvtRibbonPanel.AddStackedItems(stackButtonDatas[0].Item1, stackButtonDatas[1].Item1, stackButtonDatas[2].Item1);
+                                SetStackItemsVisible(ribbonItems, stackButtonDatas);
+                                stackButtonDatas.RemoveRange(0, 3);
+                                goto PlaceStackStart;
+                            }
+                            if (stackButtonDatas.Count == 2)
+                            {
+                                ribbonItems = rvtRibbonPanel.AddStackedItems(stackButtonDatas[0].Item1, stackButtonDatas[1].Item1);
+                                SetStackItemsVisible(ribbonItems, stackButtonDatas);
+                            }
+                            else if (stackButtonDatas.Count == 1)
+                            {
+                                pushButton = rvtRibbonPanel.AddItem(stackButtonDatas[0].Item1) as PushButton;
+                                setRibbonItemVisibleAction(pushButton, stackButtonDatas[0].Item2);
+                            }
+                            stackButtonDatas.Clear();
+                            if (isLast)
+                                continue;
+                        }
+                        #endregion
+                        //创建分割符。分割符创建条件,1,分割符之前有可见Button,2,在分割符之后的下一个可见Button之前创建分割符
+                        if (separatorStandBy && tszbuttonData.Visible)
+                        {
+                            rvtRibbonPanel.AddSeparator();
+                            separatorBeforeVisibleItem = null;
+                            separatorStandBy = false;
+                        }
+
+                        //创建pullButton
+                        if (tszbuttonData.Styles != ButtonStyles.Separator)
+                        {
+                            pushbuttonData = new PushButtonData(tszbuttonData.ButtonName, tszbuttonData.ButtonText,
+                                tszbuttonData.AssemblyName, tszbuttonData.ClassName);
+                            if (!string.IsNullOrEmpty(tszbuttonData.ImageName))
+                            {
+                                var stringImagePath = tszbuttonData.ImageName + "16.png";
+                                var stringLargeImagePath = tszbuttonData.ImageName + ".png";
+                                if (File.Exists(stringImagePath))
+                                {
+                                    pushbuttonData.Image = new BitmapImage(new Uri(stringImagePath));
+                                }
+
+                                if (File.Exists(stringLargeImagePath))
+                                {
+                                    pushbuttonData.LargeImage = new BitmapImage(new Uri(stringLargeImagePath));
+                                }
+                             
+                             
+                            }
+                            pushbuttonData.ToolTip = tszbuttonData.ToolTip;
+                            pushbuttonData.LongDescription = tszbuttonData.LongDescription;
+                            pushbuttonData.AvailabilityClassName = tszbuttonData.ClassName;
+                        }
+                        //加载图标并且将Button添加到菜单
+                        switch (tszbuttonData.Styles)
+                        {
+                            case ButtonStyles.Separator:
+                                if (separatorBeforeVisibleItem != null)
+                                    separatorStandBy = true;
+                                //rvtRibbonPanel.AddSeparator();
+                                break;
+                            case ButtonStyles.Large:
+                                pushButton = rvtRibbonPanel.AddItem(pushbuttonData) as PushButton;
+                                setRibbonItemVisibleAction(pushButton, tszbuttonData.Visible);
+                                break;
+                            case ButtonStyles.Pushdown:
+                                if (pulldownButton == null || pulldownButton.Visible == false)
+                                {
+                                    SplitButtonData spliteButtonData = new SplitButtonData("push" + panelData.PanelName + i, panelData.PanelName);
+                                    spliteButtonData.Text = pushbuttonData.Text;
+                                    spliteButtonData.LargeImage = pushbuttonData.LargeImage;
+                                    spliteButtonData.ToolTip = tszbuttonData.ToolTip;
+                                    spliteButtonData.LongDescription = tszbuttonData.LongDescription;
+
+                                    pulldownButton = rvtRibbonPanel.AddItem(spliteButtonData) as PulldownButton;
+                                    pulldownButton.Visible = tszbuttonData.Visible;
+                                    setRibbonItemVisibleAction(pulldownButton, tszbuttonData.Visible);
+                                }
+                                pushButton = pulldownButton?.AddPushButton(pushbuttonData);
+                                setRibbonItemVisibleAction(pushButton, tszbuttonData.Visible);
+                                break;
+                            case ButtonStyles.Stacked:
+                            case ButtonStyles.StackedBox:
+                                stackButtonDatas.Add(new Tuple<ButtonData, bool>(pushbuttonData, tszbuttonData.Visible));
+                                break;
+                        }
+                        //最后一项,并且是Stacked ,跳转到添加Stacked 
+                        isLast = panelData.Buttons.Count - 1 == i;
+                        if (isLast&&stackButtonDatas.Count>0)
+                            goto PlaceStackStart;
+
+                        #endregion
+                    }
+
+                }
+
+                ////调整选项卡到最前
+                RibbonTab tab = ComponentManager.Ribbon.Tabs.FirstOrDefault(t => t.Name == tabData.TabName);
+                if (tab != null)
+                {
+                    ComponentManager.Ribbon.Tabs.Remove(tab);
+                    ComponentManager.Ribbon.Tabs.Insert(index, tab);
+                    index++;
+                }
+            }
+            return true;
+        }
+        /// <summary>
+        /// Tab前后加【】
+        /// </summary>
+        /// <param name="configTabs"></param>
+        /// <returns></returns>
+        private static bool AddSignToTab(TszTabData[] configTabs)
+        {
+            var firstVisibleTabItem = configTabs.FirstOrDefault(t => t.HasVisibleItem());
+            //如果都不可见,直接返回,不创建了
+            if (firstVisibleTabItem == null) return false;
+            firstVisibleTabItem.TabName = "【"+ firstVisibleTabItem.TabName;
+            var lastVisibleTabItem = configTabs.LastOrDefault(t => t.HasVisibleItem());
+            if (lastVisibleTabItem == null) return false;
+            lastVisibleTabItem.TabName += "】";
+            return true;
+        }
+        /// <summary>
+        /// 设置StackButton的可见性
+        /// </summary>
+        /// <param name="ribbonItems"></param>
+        /// <param name="stackButtonDatas"></param>
+        private static void SetStackItemsVisible(IList<RibbonItem> ribbonItems, List<Tuple<ButtonData, bool>> stackButtonDatas)
+        {
+            int i = 0;
+            foreach (RibbonItem ribbonItem in ribbonItems)
+            {
+                var tuple = stackButtonDatas[i];
+                ribbonItem.Visible = tuple.Item2;
+                i++;
+            }
+        }
+    }
+}

+ 18 - 0
SAGA.RevitMenu/Configuration/RevitVer.cs

@@ -0,0 +1,18 @@
+using System;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    [Flags]
+    public enum RevitVer
+    {
+        R12 = 1,
+        R13 = 2,
+        R14 = 4,
+        R15 = 8,
+        R16 = 0x10,
+        R17 = 0x20,
+        R18 = 0x40,
+        Unkonw = 0
+    }
+}
+

+ 11 - 0
SAGA.RevitMenu/Configuration/StackStyles.cs

@@ -0,0 +1,11 @@
+namespace TSZ.RevitMenu.Configuration
+{
+    using System;
+
+    public enum StackStyles
+    {
+        Normal,
+        Pulldown
+    }
+}
+

+ 57 - 0
SAGA.RevitMenu/Configuration/TszButtonData.cs

@@ -0,0 +1,57 @@
+using SAGA.DotNetUtils;
+using SAGA.RevitMenu.Configuration;
+
+namespace TSZ.RevitMenu.Configuration
+{
+    using System;
+    using System.Runtime.CompilerServices;
+
+    public class TszButtonData
+    {
+        public TszButtonData(string menuTab)
+        {
+            this.MenuTab = menuTab;
+        }
+
+        public TszButtonData(TszPanelData penelData, string menuTab, string strButtonName, string strButtonText, string strImageName, string strAssemblyName, string strClassName) 
+        {
+            this.TszPanelData = penelData;
+            this.MenuTab = menuTab;
+            this.ButtonName = strButtonName;
+            this.ButtonText = strButtonText;
+            this.ImageName = strImageName;
+            this.AssemblyName = strAssemblyName;
+            this.ClassName = strClassName;
+            this.IsGroup = false;
+            this.Visible = true;
+        }
+        public string AssemblyName { get; set; }
+
+        public string ButtonName { get; set; }
+
+        public string ButtonText { get; set; }
+
+        public string ClassName { get; set; }
+
+        public string ImageName { get; set; }
+
+        public bool IsGroup { get; set; }
+
+        public string LongDescription { get; set; }
+
+        public string MenuTab { get; set; }
+
+        public StackStyles StackStyle { get; set; }
+
+        public ButtonStyles Styles { get; set; }
+
+        public string ToolTip { get; set; }
+
+        public TszPanelData TszPanelData { get; set; }
+
+        public RevitVer UseVersion { get; set; }
+
+        public bool Visible { get; set; }
+    }
+}
+

+ 143 - 0
SAGA.RevitMenu/Configuration/TszPanelData.cs

@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using SAGA.RevitUtils;
+using TSZ.RevitMenu.Configuration;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    public class TszPanelData
+    {
+        private List<TszButtonData> _mButtons;
+
+        public TszPanelData(string strPanelName, bool boolGroupFlag, string strGroupImage, ButtonStyles buttonLayers)
+        {
+            this.PanelName = strPanelName;
+            this.GroupFlag = boolGroupFlag;
+            this.GroupImage = strGroupImage;
+            this.Styles = buttonLayers;
+            this.Visible = true;
+        }
+
+        public TszButtonData[] ClearSameNameAndAppTypeButtons()
+        {
+            List<TszButtonData> list = new List<TszButtonData>();
+            foreach (TszButtonData data in this.Buttons)
+            {
+                bool flag = false;
+                foreach (TszButtonData data2 in list)
+                {
+                    if (data == data2)
+                    {
+                        flag = true;
+                        break;
+                    }
+                    if (data.ButtonName == data2.ButtonName)
+                    {
+                        if ((data.AssemblyName == data2.AssemblyName) && (data.ClassName == data2.ClassName))
+                        {
+                            flag = true;
+                            break;
+                        }
+                        data.ButtonName = data.ButtonName + Guid.NewGuid();
+                    }
+                }
+                if (!flag)
+                {
+                    list.Add(data);
+                }
+            }
+            if (list.Count <= 0)
+            {
+                return null;
+            }
+            return list.ToArray();
+        }
+
+        public bool ExistsSameName()
+        {
+            foreach (TszButtonData data in this.Buttons)
+            {
+                foreach (TszButtonData data2 in this.Buttons)
+                {
+                    if ((data != data2) && (data.ButtonName == data2.ButtonName))
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        public TszButtonData[] FilterButtons(string menuTab)
+        {
+            List<TszButtonData> list = new List<TszButtonData>();
+            foreach (TszButtonData data in this.Buttons)
+            {
+                if (data.MenuTab.IndexOf(menuTab, StringComparison.Ordinal) > -1)
+                {
+                    list.Add(data);
+                }
+            }
+            if (list.Count <= 0)
+            {
+                return null;
+            }
+            return list.ToArray();
+        }
+        /// <summary>
+        /// 验证Panel是否包含不可执行的命令
+        /// </summary>
+        /// <returns></returns>
+        public bool ValidateData()
+        {
+            foreach (TszButtonData data in this.Buttons)
+            {
+                if (data.Styles == ButtonStyles.Separator ||
+                    (!string.IsNullOrEmpty(data.AssemblyName) && File.Exists(data.AssemblyName))) continue;
+                MessageShow.Infomation(data.AssemblyName + " 不存在!");
+                return false;
+            }
+            return true;
+        }
+        /// <summary>
+        /// 有可见的Button
+        /// </summary>
+        /// <returns></returns>
+        public bool HasVisibleItem()
+        {
+            var item = this.Buttons.FirstOrDefault(t => t.Visible);
+            return item != null;
+        }
+
+        public List<TszButtonData> Buttons
+        {
+            get
+            {
+                if (this._mButtons == null)
+                {
+                    this._mButtons = new List<TszButtonData>();
+                }
+                return this._mButtons;
+            }
+        }
+
+        public bool Enabled { get; set; }
+
+        public bool GroupFlag { get; set; }
+
+        public string GroupImage { get; set; }
+
+        public string PanelName { get; set; }
+
+        public ButtonStyles Styles { get; set; }
+
+        public string Title { get; set; }
+
+        public RevitVer UseVersion { get; set; }
+
+        public bool Visible { get; set; }
+    }
+}
+

+ 86 - 0
SAGA.RevitMenu/Configuration/TszTabData.cs

@@ -0,0 +1,86 @@
+
+/* ==============================================================================
+ * 功能描述:每个 菜单tab页的信息
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/8/30
+ * ==============================================================================*/
+
+using System.Collections.Generic;
+using System.Linq;
+using TSZ.RevitMenu.Configuration;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    public class TszTabData
+    {
+        private List<TszPanelData> _mPanels;
+
+        public TszTabData(string strTabName)
+        {
+            this.TabName = strTabName;
+        }
+        /// <summary>
+        /// 获取指定名称的Button
+        /// </summary>
+        /// <param name="strFindText"></param>
+        /// <returns></returns>
+        public TszButtonData[] FindButtonItem(string strFindText)
+        {
+            List<TszButtonData> list = new List<TszButtonData>();
+            foreach (TszPanelData data in this.Panels)
+            {
+                foreach (TszButtonData data2 in data.Buttons)
+                {
+                    if ((((data2.AssemblyName != null) && (data2.AssemblyName.IndexOf(strFindText) > -1)) || ((data2.ClassName != null) && (data2.ClassName.IndexOf(strFindText) > -1))) || (((data2.ButtonName != null) && (data2.ButtonName.IndexOf(strFindText) > -1)) || ((data2.ButtonText != null) && (data2.ButtonText.IndexOf(strFindText) > -1))))
+                    {
+                        list.Add(data2);
+                    }
+                }
+            }
+            return list.ToArray();
+        }
+        /// <summary>
+        /// 验证菜单关联的命令是否存在
+        /// </summary>
+        /// <returns></returns>
+        public bool ValidateData()
+        {
+            foreach (TszPanelData data in this.Panels)
+            {
+                if (!data.ValidateData())
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+        /// <summary>
+        /// 用可用项
+        /// </summary>
+        /// <returns></returns>
+        public bool HasVisibleItem()
+        {
+            var panelData = this.Panels.FirstOrDefault(t =>t.Visible&&t.HasVisibleItem());
+            return panelData != null;
+        }
+
+        public string[] Modules { get; set; }
+
+        public List<TszPanelData> Panels
+        {
+            get
+            {
+                if (this._mPanels == null)
+                {
+                    this._mPanels = new List<TszPanelData>();
+                }
+                return this._mPanels;
+            }
+        }
+
+        public string TabName { get; set; }
+
+        public string TabText { get; set; }
+    }
+}
+

+ 359 - 0
SAGA.RevitMenu/Configuration/XmlMenuData.cs

@@ -0,0 +1,359 @@
+/* ==============================================================================
+ * 功能描述:加载Menu下的配置文件,转化为TszTabData
+ * 创 建 者:Garrett
+ * 创建日期:2018/9/17 17:56:32
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Others;
+using SAGA.RevitUtils;
+using TSZ.RevitMenu.Configuration;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    /// <summary>
+    /// MenuData
+    /// </summary>
+    class XmlMenuData
+    {
+        /// <summary>
+        /// 根据选择的项目 确定加载的菜单 建筑 结构 水暖电
+        /// </summary>
+        /// <param name="strRevitVersion"></param>
+        /// <param name="blnRevit"></param>
+        /// <returns></returns>
+        public static TszTabData[] GetConfigTabs(string strRevitVersion, out bool blnRevit)
+        {
+            blnRevit = false;
+            List<string> listFea = new List<string>();
+            FileInfo[] files = new DirectoryInfo(Path.Combine(AppBaseInfo.AppRunPath, "Menu")).GetFiles("*.xml");
+            if (files.Length == 0)
+            {
+                MessageShowBase.Infomation(@"菜单加载异常,请查看安装目录DLL\OperateLogs下的操作日志。");
+                return null;
+            }
+            Dictionary<int, string> dictionary = new Dictionary<int, string>();
+            #region 读取所有的文件,对所有的模块进行排序
+            foreach (FileInfo info3 in files)
+            {
+                try
+                {
+                    FileInfo info4 = info3;
+                    XmlDocument document = new XmlDocument();
+                    document.Load(info4.FullName);
+                    XmlElement xelem = document.DocumentElement;
+                    if (xelem == null) continue;
+                    int key = xelem.SelectSingleNode("App").SelectSingleNode("AppIndex").InnerText.Trim().ToInt();
+                    if (!dictionary.ContainsKey(key))
+                    {
+                        dictionary.Add(key, info4.FullName);
+                    }
+                }
+                catch (Exception exception)
+                {
+                    MessageShow.Show(exception, false, "");
+                }
+            }
+            #endregion
+            List<TszTabData> list2 = new List<TszTabData>();
+            List<int> pushButtonList = dictionary.Keys.ToList<int>();
+            pushButtonList.Sort();
+            foreach (int num2 in pushButtonList)
+            {
+                TszTabData[] collection = GetConfigTabs(strRevitVersion, listFea, dictionary[num2]);
+                if ((collection != null) && (collection.Length > 0))
+                {
+                    list2.AddRange(collection);
+                }
+            }
+            return list2.ToArray();
+        }
+
+
+        /// <summary>
+        /// 从菜单配置文件中读取数据,转化为为TszTabData
+        /// Tab-Panels-Buttons
+        /// </summary>
+        /// <param name="strRevitVersion"></param>
+        /// <param name="listFea"></param>
+        /// <param name="fileName"></param>
+        /// <returns></returns>
+        public static TszTabData[] GetConfigTabs(string strRevitVersion, List<string> listFea, string fileName)
+        {
+            try
+            {
+                string str = Path.Combine(AppBaseInfo.AppRunPath, "RibbonImage");
+                XmlDocument document = new XmlDocument();
+                document.Load(fileName);
+                XmlElement documentElement = document.DocumentElement;
+                List<TszPanelData> list = new List<TszPanelData>();
+                #region 获取所有的命令
+
+                foreach (XmlNode node in documentElement.SelectNodes("Panel"))
+                {
+                    string strPanelName = node.Attributes["PanelName"].Value.Trim();
+                    bool boolGroupFlag = bool.Parse(node.Attributes["GroupFlag"].Value.Trim());
+                    string str3 = node.Attributes["GroupImage"].Value.Trim();
+                    string strBtnsTyle = node.Attributes["ButtonStyles"].Value.Trim();
+                    string str5 = "Normal";
+                    string strRevitVer = node.Attributes["RevitVer"].Value.Trim();
+
+                    RevitVer revitVer = GetRevitVer(strRevitVer);
+                    ButtonStyles buttonStyle = GetButtonStyle(strBtnsTyle);
+                    StackStyles stackStyle = GetStackStyle(str5);
+                    if (str3.Length <= 0)
+                    {
+                        str3 = Path.Combine(str, "LargeImage.png");
+                    }
+                    else
+                    {
+                        str3 = Path.Combine(str, str3);
+                    }
+                    TszPanelData penelData = new TszPanelData(strPanelName, boolGroupFlag, str3, buttonStyle);
+
+                    #region 命令是否可见
+                    XmlAttribute attribute = node.Attributes["Visible"];
+                    if (attribute != null)
+                    {
+                        penelData.Visible = attribute.Value.Trim().ToBool();
+                    }
+                    #endregion
+
+                    XmlNodeList pushButtonList = node.SelectNodes("Button");
+                    List<TszButtonData> list4 = new List<TszButtonData>();
+                    foreach (XmlNode node2 in pushButtonList)
+                    {
+
+                        ButtonStyles styles3 = buttonStyle;
+                        StackStyles styles4 = stackStyle;
+                        RevitVer ver2 = revitVer;
+                        XmlAttribute attribute3 = node2.Attributes["ButtonStyles"];
+                        if (attribute3 != null)
+                        {
+                            styles3 = GetButtonStyle(attribute3.Value.Trim());
+                        }
+                        XmlAttribute attribute4 = node2.Attributes["StackStyles"];
+                        if (attribute4 != null)
+                        {
+                            styles4 = GetStackStyle(attribute4.Value.Trim());
+                        }
+                        XmlAttribute attribute5 = node2.Attributes["RevitVer"];
+                        if (attribute5 != null)
+                        {
+                            ver2 = GetRevitVer(attribute5.Value.Trim());
+                        }
+
+                        #region 调试的命令不添加
+
+                        var debugAttri = node2.Attributes["IsDebug"];
+                        if (debugAttri != null)
+                        {
+                            if (debugAttri.Value.ToBool())
+                                continue;
+                        }
+
+                        #endregion
+
+                        string menuTab = node2.SelectSingleNode("MenuTab").InnerText.Trim();
+                        string[] strArray = node2.SelectSingleNode("Modules").InnerText.Trim().Split(new char[] { ',' });
+
+                        TszButtonData data2 = null;
+
+                        if (node2.ChildNodes.Count > 6)
+                        {
+                            string strButtonName = node2.SelectSingleNode("ButtonName").InnerText.Trim();
+                            string strButtonText = node2.SelectSingleNode("ButtonText").InnerText.Trim();
+                            string str14 = node2.SelectSingleNode("ImageName").InnerText.Trim();
+                            str14 = Path.Combine(str, str14);
+                            string path = node2.SelectSingleNode("DllName").InnerText.Trim();
+                            //..\OutputDll\SpacePlugin.dll
+                            string strAssemblyName = Path.Combine(AppBaseInfo.AppRunPath, Path.GetFileName(path));
+                            string addStr = @"..\";
+                            if (path.Contains(addStr))
+                            {
+                                path = path.Replace(addStr, "");
+                                strAssemblyName = Path.Combine(AppBaseInfo.AppRunPath, path);
+                            }
+
+                            string strClassName = node2.SelectSingleNode("ClassName").InnerText.Trim();
+                            string str18 = node2.SelectSingleNode("ToolTip").InnerText.Trim();
+                            string str19 = node2.SelectSingleNode("LongDescription").InnerText.Trim();
+                            data2 = new TszButtonData(penelData, menuTab, strButtonName, strButtonText, str14,
+                                strAssemblyName, strClassName)
+                            {
+                                ToolTip = str18,
+                                LongDescription = str19
+                            };
+                        }
+                        else if (node2.ChildNodes.Count > 3)
+                        {
+                            string str20 = node2.SelectSingleNode("ButtonText").InnerText.Trim();
+                            string str21 = node2.SelectSingleNode("ImageName").InnerText.Trim();
+                            string str23 = node2.SelectSingleNode("ToolTip").InnerText.Trim();
+                            str21 = Path.Combine(str, str21);
+                            data2 = new TszButtonData(menuTab)
+                            {
+                                TszPanelData = penelData,
+                                ToolTip = str23,
+                                ButtonText = str20,
+                                ImageName = str21
+                            };
+                        }
+                        else
+                        {
+                            data2 = new TszButtonData(menuTab);
+                        }
+                        XmlAttribute btnVisibleAttri = node2.Attributes["Visible"];
+                        if (btnVisibleAttri != null)
+                        {
+                            data2.Visible = btnVisibleAttri.Value.Trim().ToBool();
+                        }
+                        data2.Styles = styles3;
+                        data2.StackStyle = styles4;
+                        data2.UseVersion = ver2;
+                        list4.Add(data2);
+                    }
+                    if (list4.Any())
+                    {
+                        penelData.Buttons.AddRange(list4);
+                        list.Add(penelData);
+                    }
+                }
+
+                #endregion
+
+                List<TszTabData> list6 = new List<TszTabData>();
+                #region 对命令进行重新分组
+                XmlNodeList list5 = documentElement.SelectNodes("Tab");
+                foreach (XmlNode node3 in list5)
+                {
+                    string strTabName = node3.Attributes["TabName"].Value.Trim();
+                    string str25 = node3.SelectSingleNode("MenuTab").InnerText.Trim();
+                    string[] strArray2 = node3.SelectSingleNode("Modules").InnerText.Trim().Split(new char[] { ',' });
+
+                    List<TszPanelData> list7 = new List<TszPanelData>();
+                    foreach (TszPanelData data5 in list)
+                    {
+                        TszButtonData[] collection = data5.FilterButtons(str25);
+                        if ((collection != null) && (collection.Length > 0))
+                        {
+                            TszPanelData data6 =
+                                new TszPanelData(data5.PanelName, data5.GroupFlag, data5.GroupImage, data5.Styles)
+                                {
+                                    Visible = data5.Visible
+                                };
+                            data6.Buttons.AddRange(collection);
+                            list7.Add(data6);
+                        }
+                    }
+                    TszTabData item = new TszTabData(strTabName)
+                    {
+                        TabText = str25,
+                        Modules = strArray2
+                    };
+
+                    if (list7.Any())
+                    {
+                        item.Panels.AddRange(list7);
+                        list6.Add(item);
+                    }
+                }
+                #endregion
+                return list6.ToArray();
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, false, "");
+                return null;
+            }
+        }
+
+
+        /// <summary>
+        /// 根据配置文件设置 获取Botton样式
+        /// </summary>
+        /// <param name="strBtnsTyle"></param>
+        /// <returns></returns>
+        public static ButtonStyles GetButtonStyle(string strBtnsTyle)
+        {
+            if (strBtnsTyle == null)
+                return ButtonStyles.Pushdown;
+            string str = strBtnsTyle.ToLower();
+
+            if (str == "separator")
+            {
+                return ButtonStyles.Separator;
+            }
+            if (str == "large")
+            {
+                return ButtonStyles.Large;
+            }
+            if (str == "pushdown")
+            {
+                return ButtonStyles.Pushdown;
+            }
+            if (str == "stacked")
+            {
+                return ButtonStyles.Stacked;
+            }
+            if (str != "stackedbox")
+            {
+                return ButtonStyles.StackedBox;
+            }
+            return ButtonStyles.Pushdown;
+        }
+        /// <summary>
+        /// 获取有哪些版本的命令可用 R14,R15,R16,R17,R18
+        /// </summary>
+        /// <param name="strRevitVer"></param>
+        /// <returns></returns>
+        public static RevitVer GetRevitVer(string strRevitVer)
+        {
+            RevitVer unkonw = RevitVer.Unkonw;
+            if (strRevitVer.ToUpper().IndexOf("R14", StringComparison.Ordinal) > -1)
+            {
+                unkonw |= RevitVer.R14;
+            }
+            if (strRevitVer.ToUpper().IndexOf("R15", StringComparison.Ordinal) > -1)
+            {
+                unkonw |= RevitVer.R15;
+            }
+            if (strRevitVer.ToUpper().IndexOf("R16", StringComparison.Ordinal) > -1)
+            {
+                unkonw |= RevitVer.R16;
+            }
+            if (strRevitVer.ToUpper().IndexOf("R17", StringComparison.Ordinal) > -1)
+            {
+                unkonw |= RevitVer.R17;
+            }
+            return unkonw;
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="strBtnsTyle"></param>
+        /// <returns></returns>
+        public static StackStyles GetStackStyle(string strBtnsTyle)
+        {
+            StackStyles normal = StackStyles.Normal;
+            if (strBtnsTyle == null) return normal;
+            string str = strBtnsTyle.ToLower();
+
+            if (str == "pulldown")
+            {
+                normal = StackStyles.Pulldown;
+            }
+            if (str == "normal")
+            {
+                normal = StackStyles.Normal;
+            }
+            return normal;
+        }
+    }
+}

+ 67 - 0
SAGA.RevitMenu/Configuration/XmlMenuDataWrapper.cs

@@ -0,0 +1,67 @@
+/* ==============================================================================
+ * 功能描述:XmlMenuDataWrapper  
+ * 创 建 者:Garrett
+ * 创建日期:2018/9/18 8:53:36
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.MBI;
+
+namespace SAGA.RevitMenu.Configuration
+{
+    /// <summary>
+    /// XmlMenuDataWrapper
+    /// </summary>
+    class XmlMenuDataWrapper
+    {
+        /// <summary>
+        /// 跟据用户权限,对菜单数据进行修饰
+        /// </summary>
+        /// <param name="tabDatas"></param>
+        public static void Wrapper(TszTabData[] tabDatas)
+        {
+            var showMenusList = ReadUserMeunPermissionData(Path.Combine(OutReachConst.MBITempSettingPath,OutReachConst.UserMenuPermission));
+            foreach (var tabData in tabDatas)       {
+                foreach (var panelData in tabData.Panels)           {
+                    foreach (var buttonData in panelData.Buttons)               {
+                        if (buttonData.ClassName.IsNotNullEmpty())
+                        {
+                            buttonData.Visible = showMenusList.Contains(buttonData.ClassName);
+                        }
+                    }
+                }
+                
+            }
+        }
+        /// <summary>
+        /// 读取用户权限数据
+        /// </summary>
+        /// <param name="fileName"></param>
+        /// <returns></returns>
+        private static List<string> ReadUserMeunPermissionData(string path)
+        {
+            List < string > list=new List<string>();
+            if (File.Exists(path))
+            {
+                using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
+                {
+                    String line;
+                    while ((line = sr.ReadLine()) != null)
+                    {
+                        //var mode = line.JsonToObject<string>();
+                        var mode = line;
+                        list.Add(mode);
+                    }
+                }
+            }
+                
+            return list;
+        }
+
+    }
+}

+ 187 - 0
SAGA.RevitMenu/Globals.cs

@@ -0,0 +1,187 @@
+using System;
+using System.IO;
+using Autodesk.Revit.DB.Events;
+using Autodesk.Revit.UI;
+using Autodesk.Revit.UI.Events;
+using SAGY.DotNetUtils;
+using SAGY.RevitMenu.Configuration;
+using SAGY.RevitUtils;
+using SAGY.RevitUtils.Extends;
+using TSZ.RevitMenu;
+using TSZ.RevitMenu.Configuration;
+
+namespace SAGY.RevitMenu
+{
+    public class Globals : IRegisterDockpaneApp
+    {
+        private static ScreenMenu _dockMenu = null;
+        private static bool _mIsHide;
+        public const string ApplicationName = "屏幕菜单";
+        public const string DiagnosticsPanelName = "屏幕菜单";
+        public static ExternalCommandData ExtCmdData = null;
+        public static DockablePaneId MLeftDockablePanelId = new DockablePaneId(new Guid("7EB1ED3F-0993-4540-B291-D17FF539F5B9"));
+        public const string ScreenMenuState = "TSZ.ScreenMenu.State";
+        public static UIControlledApplication UiApp = null;
+
+        private void application_ApplicationClosing(object sender, ApplicationClosingEventArgs e)
+        {
+            _mIsHide = false;
+            if (GetState())
+            {
+                PressHelper.KeyPress("HIDMENU");
+                _mIsHide = true;
+            }
+            SaveState(_mIsHide);
+        }
+
+        private void ControlledApplication_DocumentCreated(object sender, DocumentCreatedEventArgs e)
+        {
+            if (!e.Document.IsFamilyDocument)
+            {
+                _mIsHide = GetState();
+                IntPtr mainWindowHandle = RevitProcess.GetMainWindowHandle();
+                if (_mIsHide)
+                {
+                    PressHelper.KeyPress(mainWindowHandle, "SHOMENU");
+                }
+                else
+                {
+                    PressHelper.KeyPress(mainWindowHandle, "HIDMENU");
+                }
+            }
+        }
+
+        private void ControlledApplication_DocumentOpened(object sender, DocumentOpenedEventArgs e)
+        {
+            if (!e.Document.IsFamilyDocument)
+            {
+                IntPtr mainWindowHandle = RevitProcess.GetMainWindowHandle();
+                _mIsHide = GetState();
+                if (_mIsHide)
+                {
+                    PressHelper.KeyPress(mainWindowHandle, "SHOMENU");
+                }
+                else
+                {
+                    PressHelper.KeyPress("HIDMENU");
+                }
+                AppRegister.RegisterStructRebarCount(e.Document);
+            }
+        }
+
+        public static bool GetState()
+        {
+            try
+            {
+                IniFileOperate operate = new IniFileOperate(Path.Combine(AppBaseInfo.AppTempFilePath, "TSZ.ScreenMenu.State.ini"));
+                return operate.ReadValue("RevitMenu", "TSZ.ScreenMenu.State").ToBool();
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, true, "");
+            }
+            return true;
+        }
+
+        public static void HidePanels(ExternalCommandData cmdData)
+        {
+            SetWindowVisibility(cmdData, MLeftDockablePanelId, false);
+        }
+
+        public static void HidePanels(UIControlledApplication application)
+        {
+            SetWindowVisibility(application, MLeftDockablePanelId, false);
+        }
+
+        public bool RegisterApp(UIControlledApplication application)
+        {
+            try
+            {
+                UiApp = application;
+                _dockMenu = new ScreenMenu();
+                _dockMenu.SetInitialDockingParameters(0, 150, 0, 700, DockPosition.Bottom, Guid.Empty);
+                application.RegisterDockablePane(MLeftDockablePanelId, "屏幕菜单", _dockMenu);
+                application.ControlledApplication.DocumentCreated += new EventHandler<DocumentCreatedEventArgs>(this.ControlledApplication_DocumentCreated);
+                application.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(this.ControlledApplication_DocumentOpened);
+                application.ApplicationClosing += new EventHandler<ApplicationClosingEventArgs>(this.application_ApplicationClosing);
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, false, "");
+                return false;
+            }
+            return true;
+        }
+
+        public static void SaveState(bool state)
+        {
+            try
+            {
+                new IniFileOperate(Path.Combine(AppBaseInfo.AppTempFilePath, "TSZ.ScreenMenu.State.ini")).WriteValue("RevitMenu", "TSZ.ScreenMenu.State", state.ToString());
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, true, "");
+            }
+        }
+
+        private static void SetWindowVisibility(ExternalCommandData cmdData, DockablePaneId dockablePaneId, bool state)
+        {
+            try
+            {
+                DockablePane dockablePane = cmdData.Application.GetDockablePane(dockablePaneId);
+                if (dockablePane != null)
+                {
+                    if (state)
+                    {
+                        _dockMenu.SetCmdData(cmdData);
+                        dockablePane.Show();
+                    }
+                    else
+                    {
+                        _dockMenu.SetCmdData(cmdData);
+                        dockablePane.Hide();
+                    }
+                }
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, false, "");
+            }
+        }
+
+        private static void SetWindowVisibility(UIControlledApplication application, DockablePaneId dockablePaneId, bool state)
+        {
+            try
+            {
+                DockablePane dockablePane = application.GetDockablePane(dockablePaneId);
+                if (dockablePane != null)
+                {
+                    if (state)
+                    {
+                        dockablePane.Show();
+                    }
+                    else
+                    {
+                        dockablePane.Hide();
+                    }
+                }
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, false, "");
+            }
+        }
+
+        public static void ShowPanels(ExternalCommandData cmdData)
+        {
+            SetWindowVisibility(cmdData, MLeftDockablePanelId, true);
+        }
+
+        public static void ShowPanels(UIControlledApplication application)
+        {
+            SetWindowVisibility(application, MLeftDockablePanelId, true);
+        }
+    }
+}
+

+ 171 - 0
SAGA.RevitMenu/MenuApp.cs

@@ -0,0 +1,171 @@
+
+/* ==============================================================================
+ * 功能描述:启动revit时执行的Application
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/8/30
+ * ==============================================================================*/
+
+using System;
+using System.IO;
+using System.Windows;
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB.Events;
+using Autodesk.Revit.UI;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI.Events;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.Extend;
+using SAGA.DotNetUtils.Logger;
+using SAGA.RevitMenu.Configuration;
+using SAGA.RevitMenu.Dockpane;
+using SAGA.RevitUtils.ErrorSupports;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.Log;
+using System.Threading;
+using SAGA.RevitUtils;
+
+namespace SAGA.RevitMenu
+{
+    [Transaction(TransactionMode.Manual), Regeneration(RegenerationOption.Manual)]
+    public class MenuApp : ExternalApplication
+    {
+        public override Result OnShutdown(UIControlledApplication application)
+        {
+            ErrorHandlers.Stop();
+            RevitEventsBingding.RemoveEvents(application);
+            base.OnShutdown(application);
+            TszDocChanged -= App_DocumentChanged;
+            application.ControlledApplication.DocumentClosing -= ControlledApplication_DocumentClosing;
+            return Result.Succeeded;
+        }
+
+
+        public override Result OnStartup(UIControlledApplication application)
+        {
+            ErrorHandlers.Start();
+            base.OnStartup(application);
+         
+            StartSetting.RegiterPane(application);
+            //使用快捷键自动创建空间,需要先设置快捷键   
+            //ScreenMenuKeyBoardShortCut.SetKeyboardShortcuts(application.ControlledApplication.VersionName);
+            //记录空间设备修改;Chang时仅保存到临时文件中;Save时保存到log文件中;关闭是清除临时文件
+            TszDocChanged += App_DocumentChanged;
+            application.ControlledApplication.DocumentClosing += ControlledApplication_DocumentClosing;
+            RevitEventsBingding.AddEvents(application);
+            //将加载菜单逻辑后移 
+            if (!MenuConfig.LoadMenus(application))
+            {
+                return Result.Failed;
+            }
+            //删除Addin文件
+            MenuConfig.ClearAddInFile(application);
+            return Result.Succeeded;
+        }
+
+        private void ControlledApplication_DocumentClosing(object sender, DocumentClosingEventArgs e)
+        {
+            DocumentChangedLog.DeleteTempLog(e.Document.PathName);
+        }
+
+
+        /// <summary>
+        /// 记录操作日志
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void App_DocumentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
+        {
+            var doc = e.GetDocument();
+            if (doc.IsFamilyDocument) return;
+            var pathName = doc.PathName;
+            //楼层文件名称,无后缀
+            var docName = pathName.GetFileName();
+            
+            Func<ElementId, string> getTypeName = (elementId) => doc.GetElement(elementId).GetType().Name;
+            Func<ElementId, string> getFamilyName = (elementId) => doc.GetElement(elementId).GetFamily()?.Name;
+            Func<ElementId, string> getCategory = (elementId) => doc.GetElement(elementId).GetCategory().ToString();
+            //删除
+            var deletes = e.GetDeletedElementIds();
+            if (deletes.Count > 0)
+            {
+                foreach (var elementId in deletes)
+                {
+                    DocumentChangedLogMode mode = new DocumentChangedLogMode();
+                    mode.DataTime = DateTime.Now.ToString();
+                    mode.DocPath = pathName;
+                    mode.DocName = docName;
+                    mode.Operator = DocumentChangedOperator.Delete.ToString();
+                    mode.Id = elementId.ToString();
+                    
+                    DocumentChangedLog.Log(mode.DocPath, mode.ToJson());
+                }
+            }
+            //增加
+            var adds = e.GetAddedElementIds();
+            if (adds.Count > 0)
+            {
+                foreach (var elementId in adds)
+                {
+                    //if(!IsWatchType(doc,elementId))continue;
+                    DocumentChangedLogMode mode = new DocumentChangedLogMode();
+                    mode.DataTime = DateTime.Now.ToString();
+                    mode.DocPath = pathName;
+                    mode.DocName = docName;
+                    mode.Operator = DocumentChangedOperator.Add.ToString();
+                    mode.Id = elementId.ToString();
+                    mode.Type = getTypeName(elementId);
+                    mode.Family = getFamilyName(elementId);
+                    mode.Category = getCategory(elementId);
+                    DocumentChangedLog.Log(mode.DocPath, mode.ToJson());
+                }
+            }
+            //修改
+            var modifieds = e.GetModifiedElementIds();
+            if (modifieds.Count > 0)
+            {
+                foreach (var elementId in modifieds)
+                {
+                    //if (!IsWatchType(doc, elementId)) continue;
+                    DocumentChangedLogMode mode = new DocumentChangedLogMode();
+                    mode.DataTime = DateTime.Now.ToString();
+                    mode.DocPath = pathName;
+                    mode.DocName = docName;
+                    mode.Operator = DocumentChangedOperator.Modified.ToString();
+                    mode.Id = elementId.ToString();
+                    mode.Type = getTypeName(elementId);
+                    mode.Family = getFamilyName(elementId);
+                    mode.Category = getCategory(elementId);
+                    DocumentChangedLog.Log(mode.DocPath, mode.ToJson());
+                }
+            }
+        }
+        /// <summary>
+        /// 是否为需要监视的类型
+        /// </summary>
+        /// <param name="doc"></param>
+        /// <param name="elementId"></param>
+        /// <returns></returns>
+        private bool IsWatchType(Document doc, ElementId elementId)
+        {
+            var type = doc.GetElement(elementId).GetType().Name;
+            //族类型命名规则具有特殊性,不做有判定依据
+            var family = doc.GetElement(elementId).GetFamily()?.Name;
+            bool result = false;
+            switch (type)
+            {
+                case "SpaceTag":
+                    result = true;
+                    break;
+                case "Space":
+                    result = true;
+                    break;
+                case "FamilyInstance":
+                    result = true;
+                    break;
+            }
+            return result;
+        }
+        
+    }
+}
+

+ 36 - 0
SAGA.RevitMenu/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("SAGA.RevitMenu")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SAGA.RevitMenu")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("066ec682-baa8-4cf8-aae0-f08b962ba1dd")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 214 - 0
SAGA.RevitMenu/SAGA.RevitMenu.csproj

@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SAGA.RevitMenu</RootNamespace>
+    <AssemblyName>SAGA.RevitMenu</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R18|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R17|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R18|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\R18\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R17|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\R17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R18|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\R18\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R17|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\R17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RR17|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RR17|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\RR17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RR17|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\RR17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="AdWindows">
+      <HintPath>..\Dlls\RevitRefDll\AdWindows.dll</HintPath>
+    </Reference>
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="RevitAddInUtility">
+      <HintPath>..\Dlls\RevitRefDll\RevitAddInUtility.dll</HintPath>
+    </Reference>
+    <Reference Include="RevitAPI">
+      <HintPath>..\Dlls\RevitRefDll\RevitAPI.dll</HintPath>
+    </Reference>
+    <Reference Include="RevitAPIUI">
+      <HintPath>..\Dlls\RevitRefDll\RevitAPIUI.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.DotNetUtils">
+      <HintPath>..\Dlls\SAGA.DotNetUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.RevitUtils">
+      <HintPath>..\Dlls\SAGA.RevitUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xaml" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Addin\RevitProductExt.cs" />
+    <Compile Include="Addin\RevitStartHelper.cs" />
+    <Compile Include="Addin\RevitVersionExt.cs" />
+    <Compile Include="Configuration\ButtonStyles.cs" />
+    <Compile Include="Configuration\MenuConfig.cs" />
+    <Compile Include="Configuration\XmlMenuData.cs" />
+    <Compile Include="Configuration\RevitRibbonOperate.cs" />
+    <Compile Include="Configuration\RevitVer.cs" />
+    <Compile Include="Configuration\StackStyles.cs" />
+    <Compile Include="Configuration\TszButtonData.cs" />
+    <Compile Include="Configuration\TszPanelData.cs" />
+    <Compile Include="Configuration\TszTabData.cs" />
+    <Compile Include="Configuration\XmlMenuDataWrapper.cs" />
+    <Compile Include="Setting\StartSetting.cs" />
+    <Compile Include="MenuApp.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShortKey\ScreenMenuKeyBoardShortCut.cs" />
+    <Compile Include="ShortKey\ShortKeyHelper.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="ShortKey\KeyboardShortcuts.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Connected Services\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 6 - 0
SAGA.RevitMenu/SAGA.RevitMenu.csproj.user

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectView>ProjectFiles</ProjectView>
+  </PropertyGroup>
+</Project>

+ 217 - 0
SAGA.RevitMenu/ScreenMenu.cs

@@ -0,0 +1,217 @@
+using SAGY.RevitMenu;
+using SAGY.RevitMenu.Configuration;
+
+namespace TSZ.RevitMenu
+{
+    using Autodesk.Revit.UI;
+    using System;
+    using System.CodeDom.Compiler;
+    using System.ComponentModel;
+    using System.Diagnostics;
+    using System.Drawing;
+    using System.IO;
+    using System.Windows;
+    using System.Windows.Controls;
+    using System.Windows.Forms;
+    using System.Windows.Forms.Integration;
+    using System.Windows.Markup;
+    using TSZ.RevitBaseDll.Extends;
+    using TSZ.RevitMenu.Configuration;
+
+    public class ScreenMenu : Page, IDockablePaneProvider, IComponentConnector
+    {
+        private bool _contentLoaded;
+        private TszButtonData _curCmd;
+        private ExternalCommandData _extCmdData;
+        private ExternalEvent _externalEvent;
+        private RvtCmdExternalEventHandler _handler;
+        private int m_bottom = 1;
+        private int m_left = 1;
+        private DockPosition m_position = DockPosition.Bottom;
+        private int m_right = 1;
+        private Guid m_targetGuid;
+        private int m_top = 1;
+        internal OutlookBar obMenu;
+
+        public ScreenMenu()
+        {
+            this.InitializeComponent();
+            this._handler = new RvtCmdExternalEventHandler(this._extCmdData);
+            this._externalEvent = ExternalEvent.Create(this._handler);
+        }
+
+        [GeneratedCode("PresentationBuildTasks", "4.0.0.0"), DebuggerNonUserCode]
+        internal Delegate _CreateDelegate(System.Type delegateType, string handler)
+        {
+            return Delegate.CreateDelegate(delegateType, this, handler);
+        }
+
+        private void Host_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            this.obMenu.UpdateSize(e.NewSize.Width, e.NewSize.Height);
+        }
+
+        [GeneratedCode("PresentationBuildTasks", "4.0.0.0"), DebuggerNonUserCode]
+        public void InitializeComponent()
+        {
+            if (!this._contentLoaded)
+            {
+                this._contentLoaded = true;
+                Uri resourceLocator = new Uri("/TSZ.RevitMenu;component/screenmenu.xaml", UriKind.Relative);
+                System.Windows.Application.LoadComponent(this, resourceLocator);
+            }
+        }
+
+        private void Page_FocusableChanged(object sender, DependencyPropertyChangedEventArgs e)
+        {
+            this.UpdateSize();
+        }
+
+        public void PanelEvent(object sender, EventArgs e)
+        {
+            try
+            {
+                if (this._extCmdData != null)
+                {
+                    System.Windows.Forms.Control control = (System.Windows.Forms.Control) sender;
+                    this._curCmd = control.Tag as TszButtonData;
+                    if (this._curCmd != null)
+                    {
+                        this._extCmdData.Application.ActiveViewFocus();
+                        this._handler.CurBtnCmd = this._curCmd;
+                        this._externalEvent.Raise();
+                        this.UpdateSize();
+                    }
+                }
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, false, "");
+            }
+        }
+
+        private void ScreenMenu_OnLoaded(object sender, RoutedEventArgs e)
+        {
+            if (this.obMenu.Controls.Count <= 0)
+            {
+                try
+                {
+                    bool blnRevit = false;
+                    foreach (TszTabData data in MenuConfig.GetConfigTabs(Globals.UiApp.ControlledApplication.VersionNumber, out blnRevit))
+                    {
+                        if (data.TabText != "MTSMENU")
+                        {
+                            CmdPanel panel = new CmdPanel();
+                            this.obMenu.AddTabButton(data.TabName, panel);
+                            foreach (TszPanelData data2 in data.Panels)
+                            {
+                                foreach (TszButtonData data3 in data2.Buttons)
+                                {
+                                    string path = data3.ImageName + "16.png";
+                                    if (File.Exists(path))
+                                    {
+                                        string caption = data3.ButtonText.Replace(" ", "").Replace("\r\n", "").Replace("\n", "");
+                                        panel.AddCmdButton(caption, System.Drawing.Image.FromFile(path), data3, new EventHandler(this.PanelEvent));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    this.obMenu.SelectTabButton(0);
+                }
+                catch (Exception exception)
+                {
+                    MessageShow.Show(exception, false, "");
+                }
+            }
+        }
+
+        public void SetCmdData(ExternalCommandData cmdData)
+        {
+            this.ExtCmdData = cmdData;
+            if (this._handler != null)
+            {
+                this._handler.ExtCmdData = cmdData;
+            }
+        }
+
+        public void SetInitialDockingParameters(int left, int right, int top, int bottom, DockPosition position, Guid targetGuid)
+        {
+            this.m_position = position;
+            this.m_left = left;
+            this.m_right = right;
+            this.m_top = top;
+            this.m_bottom = bottom;
+            this.m_targetGuid = targetGuid;
+        }
+
+        public void SetupDockablePane(DockablePaneProviderData data)
+        {
+            DockablePaneId id;
+            data.FrameworkElement = this;
+            data.InitialState = new DockablePaneState();
+            data.InitialState.DockPosition = this.m_position;
+            if (this.m_targetGuid == Guid.Empty)
+            {
+                id = null;
+            }
+            else
+            {
+                id = new DockablePaneId(this.m_targetGuid);
+            }
+            if (this.m_position == DockPosition.Tabbed)
+            {
+                data.InitialState.TabBehind = id;
+            }
+            if (this.m_position == DockPosition.Floating)
+            {
+                data.InitialState.SetFloatingRectangle(new Autodesk.Revit.UI.Rectangle(this.m_left, this.m_top, this.m_right, this.m_bottom));
+            }
+        }
+
+        [GeneratedCode("PresentationBuildTasks", "4.0.0.0"), EditorBrowsable(EditorBrowsableState.Never), DebuggerNonUserCode]
+        void IComponentConnector.Connect(int connectionId, object target)
+        {
+            switch (connectionId)
+            {
+                case 1:
+                    ((ScreenMenu) target).Loaded += new RoutedEventHandler(this.ScreenMenu_OnLoaded);
+                    ((ScreenMenu) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
+                    ((ScreenMenu) target).FocusableChanged += new DependencyPropertyChangedEventHandler(this.Page_FocusableChanged);
+                    return;
+
+                case 2:
+                    ((WindowsFormsHost) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
+                    ((WindowsFormsHost) target).FocusableChanged += new DependencyPropertyChangedEventHandler(this.Page_FocusableChanged);
+                    return;
+
+                case 3:
+                    ((Grid) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
+                    return;
+
+                case 4:
+                    ((WindowsFormsHost) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
+                    return;
+
+                case 5:
+                    this.obMenu = (OutlookBar) target;
+                    return;
+            }
+            this._contentLoaded = true;
+        }
+
+        private void UpdateSize()
+        {
+            this.obMenu.UpdateSize(base.RenderSize.Width, base.RenderSize.Height);
+        }
+
+        public ExternalCommandData ExtCmdData
+        {
+            set
+            {
+                this._extCmdData = value;
+            }
+        }
+    }
+}
+

+ 27 - 0
SAGA.RevitMenu/SetMenuCmd.cs

@@ -0,0 +1,27 @@
+using System.Windows.Forms;
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using SAGY.RevitUtils;
+
+namespace SAGY.RevitMenu
+{
+    [Regeneration(RegenerationOption.Manual), Transaction(TransactionMode.Manual)]
+    public class SetMenuCmd : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
+            {
+                return Result.Cancelled;
+            }
+            SetMenuForm form = new SetMenuForm();
+            if (form.ShowDialog(base.WinImpl) == DialogResult.OK)
+            {
+                MessageShow.Infomation("重新启动后菜单设置生效!");
+            }
+            return Result.Succeeded;
+        }
+    }
+}
+

+ 552 - 0
SAGA.RevitMenu/SetMenuForm.cs

@@ -0,0 +1,552 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Windows.Forms;
+using Autodesk.Revit.DB;
+using SAGY.DotNetUtils;
+using SAGY.DotNetUtils.Configration;
+using SAGY.DotNetUtils.WinForms;
+using TSZ.RevitMenu.Configuration;
+using ComboBox = Autodesk.Revit.UI.ComboBox;
+using Tab = TSZ.RevitMenu.Configuration.Tab;
+
+namespace SAGY.RevitMenu
+{
+    public class SetMenuForm : BaseForm
+    {
+        private System.Windows.Forms.Button bn_Up;
+        private System.Windows.Forms.Button btn_Add;
+        private System.Windows.Forms.Button btn_Cancle;
+        private System.Windows.Forms.Button btn_Delete;
+        private System.Windows.Forms.Button btn_Down;
+        private System.Windows.Forms.Button btn_OK;
+        private System.Windows.Forms.Button btn_ReSet;
+        private ComboBox comboBox1;
+        private ComboBox comboBox2;
+        private IContainer components;
+        private GroupBox groupBox1;
+        private GroupBox groupBox2;
+        private Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> newDic = new Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>>();
+        private Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> originDic = new Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>>();
+        private TreeView treeView1;
+        private TreeView treeView2;
+        private List<string> xmlFile = new List<string>();
+
+        public SetMenuForm()
+        {
+            this.InitializeComponent();
+        }
+
+        private void bn_Up_Click(object sender, EventArgs e)
+        {
+            if ((this.treeView2.SelectedNode != null) && (this.treeView2.SelectedNode.Parent != null))
+            {
+                if (this.treeView2.SelectedNode.Index > 0)
+                {
+                    TreeNode selectedNode = this.treeView2.SelectedNode;
+                    int index = this.treeView2.SelectedNode.Index;
+                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(index--);
+                    this.treeView2.SelectedNode.Parent.Nodes.Insert(index, selectedNode);
+                }
+                else if (this.treeView2.SelectedNode.Parent.Index > 0)
+                {
+                    TreeNode node = this.treeView2.SelectedNode;
+                    int num2 = this.treeView2.SelectedNode.Index;
+                    int num3 = this.treeView2.SelectedNode.Parent.Index;
+                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(num2);
+                    this.treeView2.Nodes[num3 - 1].Nodes.Add(node);
+                }
+                this.ChangeData();
+            }
+        }
+
+        private void btn_Add_Click(object sender, EventArgs e)
+        {
+            Dictionary<TreeNode, TreeNode> dictionary = new Dictionary<TreeNode, TreeNode>();
+            foreach (TreeNode node in this.treeView1.Nodes)
+            {
+                if ((node.Nodes != null) || (node.Nodes.Count > 0))
+                {
+                    foreach (TreeNode node2 in node.Nodes)
+                    {
+                        if (node2.Checked)
+                        {
+                            dictionary.Add(node2, node2.Parent);
+                        }
+                    }
+                }
+            }
+            List<string> list = new List<string>();
+            List<TreeNode> list2 = new List<TreeNode>();
+            foreach (KeyValuePair<TreeNode, TreeNode> pair in dictionary)
+            {
+                if (!list.Contains(pair.Value.Text))
+                {
+                    list.Add(pair.Value.Text);
+                    TreeNode item = new TreeNode(pair.Value.Text) {
+                        Tag = pair.Value.Tag
+                    };
+                    list2.Add(item);
+                }
+            }
+            int num = 0;
+            foreach (string str in list)
+            {
+                bool flag = false;
+                foreach (TreeNode node4 in this.treeView2.Nodes)
+                {
+                    if (str == node4.Text)
+                    {
+                        flag = true;
+                        break;
+                    }
+                }
+                if (!flag)
+                {
+                    new TreeNode(str);
+                    this.treeView2.Nodes.Add(list2[num]);
+                }
+                num++;
+            }
+            foreach (KeyValuePair<TreeNode, TreeNode> pair2 in dictionary)
+            {
+                foreach (TreeNode node5 in this.treeView2.Nodes)
+                {
+                    if (((node5.Nodes == null) && (node5.Nodes.Count <= 0)) || !(node5.Text == pair2.Value.Text))
+                    {
+                        continue;
+                    }
+                    bool flag2 = false;
+                    foreach (TreeNode node6 in node5.Nodes)
+                    {
+                        if (node6.Text == pair2.Key.Text)
+                        {
+                            flag2 = true;
+                            break;
+                        }
+                    }
+                    if (!flag2)
+                    {
+                        node5.Nodes.Add(pair2.Key.Clone() as TreeNode);
+                    }
+                }
+            }
+            this.ChangeData();
+        }
+
+        private void btn_Cancle_Click(object sender, EventArgs e)
+        {
+            base.Close();
+            base.DialogResult = DialogResult.Cancel;
+        }
+
+        private void btn_Delete_Click(object sender, EventArgs e)
+        {
+            for (int i = 0; i < this.treeView2.Nodes.Count; i++)
+            {
+                TreeNode node = this.treeView2.Nodes[i];
+                if (node.Checked)
+                {
+                    node.Remove();
+                    i--;
+                }
+                else
+                {
+                    for (int j = 0; j < node.Nodes.Count; j++)
+                    {
+                        if (node.Nodes[j].Checked)
+                        {
+                            node.Nodes[j].Remove();
+                            j--;
+                        }
+                    }
+                }
+            }
+            this.ChangeData();
+        }
+
+        private void btn_Down_Click(object sender, EventArgs e)
+        {
+            if ((this.treeView2.SelectedNode != null) && (this.treeView2.SelectedNode.Parent != null))
+            {
+                if (this.treeView2.SelectedNode.Index < (this.treeView2.SelectedNode.Parent.Nodes.Count - 1))
+                {
+                    TreeNode selectedNode = this.treeView2.SelectedNode;
+                    int index = this.treeView2.SelectedNode.Index;
+                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(index++);
+                    this.treeView2.SelectedNode.Parent.Nodes.Insert(index, selectedNode);
+                }
+                else if (this.treeView2.SelectedNode.Parent.Index < (this.treeView2.Nodes.Count - 1))
+                {
+                    TreeNode node = this.treeView2.SelectedNode;
+                    int num2 = this.treeView2.SelectedNode.Index;
+                    int num3 = this.treeView2.SelectedNode.Parent.Index;
+                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(num2);
+                    this.treeView2.Nodes[num3 + 1].Nodes.Insert(0, node);
+                }
+                this.ChangeData();
+            }
+        }
+
+        private void btn_OK_Click(object sender, EventArgs e)
+        {
+            List<Menus> list = new List<Menus>();
+            string strPath = Path.Combine(AppBaseInfo.AppRunPath, "Menu");
+            string path = Path.Combine(Path.Combine(AppBaseInfo.AppTempFilePath, "Menu"), AppBaseInfo.LoadArgs);
+            this.ReadXML(this.xmlFile, list, strPath);
+            foreach (Menus menus in list)
+            {
+                string appName = menus.App.AppName;
+                List<Tab> list2 = new List<Tab>();
+                List<TSZ.RevitMenu.Configuration.Panel> list3 = new List<TSZ.RevitMenu.Configuration.Panel>();
+                foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in this.newDic)
+                {
+                    if (pair.Key.Modules == appName)
+                    {
+                        list2.Add(pair.Key);
+                        list3.AddRange(pair.Value);
+                    }
+                }
+                if (list2.Count > 0)
+                {
+                    menus.Tab = list2.ToArray();
+                }
+                if (list3.Count > 0)
+                {
+                    menus.Panel = list3.ToArray();
+                }
+                if (!Directory.Exists(path))
+                {
+                    Directory.CreateDirectory(path);
+                }
+                XMLFile.SaveXMLFile<Menus>(Path.Combine(path, appName + ".xml"), menus);
+            }
+            base.DialogResult = DialogResult.OK;
+        }
+
+        private void btn_ReSet_Click(object sender, EventArgs e)
+        {
+            string path = Path.Combine(Path.Combine(AppBaseInfo.AppTempFilePath, "Menu"), AppBaseInfo.LoadArgs);
+            if (Directory.Exists(path))
+            {
+                DirectoryInfo info = new DirectoryInfo(path);
+                foreach (FileInfo info2 in info.GetFiles("*.xml"))
+                {
+                    info2.Delete();
+                }
+            }
+            base.DialogResult = DialogResult.OK;
+        }
+
+        private void ChangeData()
+        {
+            foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in this.newDic)
+            {
+                if (pair.Key.TabName == this.comboBox2.Text)
+                {
+                    Tab key = pair.Key;
+                    this.newDic.Remove(pair.Key);
+                    List<TSZ.RevitMenu.Configuration.Panel> list = new List<TSZ.RevitMenu.Configuration.Panel>();
+                    foreach (TreeNode node in this.treeView2.Nodes)
+                    {
+                        TSZ.RevitMenu.Configuration.Panel tag = node.Tag as TSZ.RevitMenu.Configuration.Panel;
+                        TSZ.RevitMenu.Configuration.Button[] buttonArray = new TSZ.RevitMenu.Configuration.Button[node.Nodes.Count];
+                        for (int i = 0; i < node.Nodes.Count; i++)
+                        {
+                            buttonArray[i] = node.Nodes[i].Tag as TSZ.RevitMenu.Configuration.Button;
+                            buttonArray[i].MenuTab = pair.Key.MenuTab;
+                            buttonArray[i].Modules = pair.Key.Modules;
+                        }
+                        tag.Button = buttonArray;
+                        list.Add(tag);
+                    }
+                    this.newDic.Add(key, list);
+                    break;
+                }
+            }
+        }
+
+        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            this.LoadTreeView(this.comboBox1, this.comboBox1.Text, this.treeView1, this.originDic);
+        }
+
+        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            this.LoadTreeView(this.comboBox2, this.comboBox2.Text, this.treeView2, this.newDic);
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (this.components != null))
+            {
+                this.components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        private void GetDictionary(List<Menus> menus, Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> dic)
+        {
+            List<Tab> list = new List<Tab>();
+            List<TSZ.RevitMenu.Configuration.Panel> list2 = new List<TSZ.RevitMenu.Configuration.Panel>();
+            for (int i = 0; i < menus.Count; i++)
+            {
+                list.AddRange(menus[i].Tab);
+                list2.AddRange(menus[i].Panel);
+            }
+            foreach (Tab tab in list)
+            {
+                List<TSZ.RevitMenu.Configuration.Panel> list3 = new List<TSZ.RevitMenu.Configuration.Panel>();
+                foreach (TSZ.RevitMenu.Configuration.Panel panel in list2)
+                {
+                    if (((panel.Button.Length > 0) && (panel.Button[0].MenuTab == tab.MenuTab)) && (panel.Button[0].Modules == tab.Modules))
+                    {
+                        list3.Add(panel);
+                    }
+                }
+                dic.Add(tab, list3);
+            }
+        }
+
+        private void InitializeComponent()
+        {
+            this.comboBox1 = new ComboBox();
+            this.btn_Add = new System.Windows.Forms.Button();
+            this.btn_Delete = new System.Windows.Forms.Button();
+            this.bn_Up = new System.Windows.Forms.Button();
+            this.btn_Down = new System.Windows.Forms.Button();
+            this.btn_OK = new System.Windows.Forms.Button();
+            this.btn_Cancle = new System.Windows.Forms.Button();
+            this.treeView1 = new TreeView();
+            this.treeView2 = new TreeView();
+            this.groupBox1 = new GroupBox();
+            this.groupBox2 = new GroupBox();
+            this.comboBox2 = new ComboBox();
+            this.btn_ReSet = new System.Windows.Forms.Button();
+            this.groupBox1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
+            base.SuspendLayout();
+            this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
+            this.comboBox1.FormattingEnabled = true;
+            this.comboBox1.Location = new Point(6, 0x10);
+            this.comboBox1.Name = "comboBox1";
+            this.comboBox1.Size = new Size(0x9e, 20);
+            this.comboBox1.TabIndex = 0;
+            this.comboBox1.SelectedIndexChanged += new EventHandler(this.comboBox1_SelectedIndexChanged);
+            this.btn_Add.Location = new Point(370, 0x4a);
+            this.btn_Add.Name = "btn_Add";
+            this.btn_Add.Size = new Size(0x4b, 0x17);
+            this.btn_Add.TabIndex = 4;
+            this.btn_Add.Text = "添加";
+            this.btn_Add.UseVisualStyleBackColor = true;
+            this.btn_Add.Click += new EventHandler(this.btn_Add_Click);
+            this.btn_Delete.Location = new Point(370, 0x71);
+            this.btn_Delete.Name = "btn_Delete";
+            this.btn_Delete.Size = new Size(0x4b, 0x17);
+            this.btn_Delete.TabIndex = 5;
+            this.btn_Delete.Text = "删除";
+            this.btn_Delete.UseVisualStyleBackColor = true;
+            this.btn_Delete.Click += new EventHandler(this.btn_Delete_Click);
+            this.bn_Up.Location = new Point(370, 0x9c);
+            this.bn_Up.Name = "bn_Up";
+            this.bn_Up.Size = new Size(0x4b, 0x17);
+            this.bn_Up.TabIndex = 6;
+            this.bn_Up.Text = "上移";
+            this.bn_Up.UseVisualStyleBackColor = true;
+            this.bn_Up.Click += new EventHandler(this.bn_Up_Click);
+            this.btn_Down.Location = new Point(370, 0xc7);
+            this.btn_Down.Name = "btn_Down";
+            this.btn_Down.Size = new Size(0x4b, 0x17);
+            this.btn_Down.TabIndex = 7;
+            this.btn_Down.Text = "下移";
+            this.btn_Down.UseVisualStyleBackColor = true;
+            this.btn_Down.Click += new EventHandler(this.btn_Down_Click);
+            this.btn_OK.Location = new Point(0x114, 0x139);
+            this.btn_OK.Name = "btn_OK";
+            this.btn_OK.Size = new Size(0x4b, 0x17);
+            this.btn_OK.TabIndex = 8;
+            this.btn_OK.Text = "确定";
+            this.btn_OK.UseVisualStyleBackColor = true;
+            this.btn_OK.Click += new EventHandler(this.btn_OK_Click);
+            this.btn_Cancle.Location = new Point(370, 0x139);
+            this.btn_Cancle.Name = "btn_Cancle";
+            this.btn_Cancle.Size = new Size(0x4b, 0x17);
+            this.btn_Cancle.TabIndex = 9;
+            this.btn_Cancle.Text = "取消";
+            this.btn_Cancle.UseVisualStyleBackColor = true;
+            this.btn_Cancle.Click += new EventHandler(this.btn_Cancle_Click);
+            this.treeView1.CheckBoxes = true;
+            this.treeView1.Location = new Point(6, 0x21);
+            this.treeView1.Name = "treeView1";
+            this.treeView1.Size = new Size(0x9e, 0xfd);
+            this.treeView1.TabIndex = 10;
+            this.treeView1.AfterCheck += new TreeViewEventHandler(this.treeView1_AfterCheck);
+            this.treeView2.CheckBoxes = true;
+            this.treeView2.Location = new Point(6, 0x21);
+            this.treeView2.Name = "treeView2";
+            this.treeView2.Size = new Size(0x9e, 0xfd);
+            this.treeView2.TabIndex = 11;
+            this.treeView2.AfterCheck += new TreeViewEventHandler(this.treeView2_AfterCheck);
+            this.groupBox1.Controls.Add(this.treeView1);
+            this.groupBox1.Controls.Add(this.comboBox1);
+            this.groupBox1.Location = new Point(12, 0x10);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new Size(0xa9, 0x126);
+            this.groupBox1.TabIndex = 14;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "设置前菜单";
+            this.groupBox2.Controls.Add(this.comboBox2);
+            this.groupBox2.Controls.Add(this.treeView2);
+            this.groupBox2.Location = new Point(0xbb, 0x10);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new Size(0xa9, 0x126);
+            this.groupBox2.TabIndex = 15;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "设置后菜单";
+            this.comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
+            this.comboBox2.FormattingEnabled = true;
+            this.comboBox2.Location = new Point(6, 0x10);
+            this.comboBox2.Name = "comboBox2";
+            this.comboBox2.Size = new Size(0x9e, 20);
+            this.comboBox2.TabIndex = 11;
+            this.comboBox2.SelectedIndexChanged += new EventHandler(this.comboBox2_SelectedIndexChanged);
+            this.btn_ReSet.Location = new Point(0xb0, 0x13c);
+            this.btn_ReSet.Name = "btn_ReSet";
+            this.btn_ReSet.Size = new Size(0x4b, 0x17);
+            this.btn_ReSet.TabIndex = 0x10;
+            this.btn_ReSet.Text = "恢复设置";
+            this.btn_ReSet.UseVisualStyleBackColor = true;
+            this.btn_ReSet.Click += new EventHandler(this.btn_ReSet_Click);
+            base.AutoScaleDimensions = new SizeF(6f, 12f);
+            base.AutoScaleMode = AutoScaleMode.Font;
+            base.ClientSize = new Size(0x1c5, 350);
+            base.Controls.Add(this.btn_ReSet);
+            base.Controls.Add(this.groupBox2);
+            base.Controls.Add(this.groupBox1);
+            base.Controls.Add(this.btn_Cancle);
+            base.Controls.Add(this.btn_OK);
+            base.Controls.Add(this.btn_Down);
+            base.Controls.Add(this.bn_Up);
+            base.Controls.Add(this.btn_Delete);
+            base.Controls.Add(this.btn_Add);
+            base.MaximizeBox = false;
+            base.MinimizeBox = false;
+            base.Name = "SetMenuForm";
+            this.Text = "设置菜单";
+            base.Load += new EventHandler(this.SetMenuForm_Load);
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox2.ResumeLayout(false);
+            base.ResumeLayout(false);
+        }
+
+        private void LoadData(ComboBox cmb, Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> dic)
+        {
+            foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in dic)
+            {
+                cmb.Items.Add(pair.Key.TabName);
+            }
+            if (cmb.Items.Count > 0)
+            {
+                cmb.SelectedIndex = 0;
+            }
+        }
+
+        private void LoadTreeView(ComboBox cmb, string tabName, TreeView tv, Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> dic)
+        {
+            tv.Nodes.Clear();
+            foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in dic)
+            {
+                if (pair.Key.TabName == tabName)
+                {
+                    foreach (TSZ.RevitMenu.Configuration.Panel panel in pair.Value)
+                    {
+                        TreeNode node = new TreeNode(panel.PanelName) {
+                            Tag = panel
+                        };
+                        foreach (TSZ.RevitMenu.Configuration.Button button in panel.Button)
+                        {
+                            if (button.ButtonStyles == "Separator")
+                            {
+                                button.ButtonText = "——";
+                            }
+                            TreeNode node2 = new TreeNode(button.ButtonText) {
+                                Tag = button
+                            };
+                            node.Nodes.Add(node2);
+                        }
+                        tv.Nodes.Add(node);
+                    }
+                }
+            }
+        }
+
+        private void ReadXML(List<string> xmlFile, List<Menus> menus, string strPath)
+        {
+            DirectoryInfo info = new DirectoryInfo(strPath);
+            foreach (FileInfo info2 in info.GetFiles("*.xml"))
+            {
+                Menus x = new Menus();
+                if (xmlFile.Contains(Path.GetFileNameWithoutExtension(info2.FullName)))
+                {
+                    XMLFile.OpenXMLFile<Menus>(info2.FullName, ref x);
+                    menus.Add(x);
+                }
+            }
+        }
+
+        private void SetMenuForm_Load(object sender, EventArgs e)
+        {
+            this.xmlFile.AddRange(AppBaseInfo.LoadArgs.ToString().Split(new char[] { ',' }));
+            List<Menus> menus = new List<Menus>();
+            List<Menus> list2 = new List<Menus>();
+            string strPath = Path.Combine(AppBaseInfo.AppRunPath, "Menu");
+            string path = Path.Combine(AppBaseInfo.AppTempFilePath, "Menu");
+            this.ReadXML(this.xmlFile, menus, strPath);
+            if (Directory.Exists(path))
+            {
+                this.ReadXML(this.xmlFile, list2, path);
+            }
+            this.GetDictionary(menus, this.originDic);
+            if ((list2 != null) && (list2.Count > 0))
+            {
+                this.GetDictionary(list2, this.newDic);
+            }
+            else
+            {
+                this.newDic = this.originDic;
+            }
+            this.LoadData(this.comboBox1, this.originDic);
+            this.LoadData(this.comboBox2, this.newDic);
+        }
+
+        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
+        {
+            TreeViewChecked(e);
+        }
+
+        private void treeView2_AfterCheck(object sender, TreeViewEventArgs e)
+        {
+            TreeViewChecked(e);
+        }
+
+        private static void TreeViewChecked(TreeViewEventArgs e)
+        {
+            if (e.Action != TreeViewAction.Unknown)
+            {
+                if (e.Node.Parent == null)
+                {
+                    foreach (TreeNode node in e.Node.Nodes)
+                    {
+                        node.Checked = e.Node.Checked;
+                    }
+                }
+                else if (!e.Node.Checked)
+                {
+                    e.Node.Parent.Checked = e.Node.Checked;
+                }
+            }
+        }
+    }
+}
+

+ 37 - 0
SAGA.RevitMenu/Setting/StartSetting.cs

@@ -0,0 +1,37 @@
+/* ==============================================================================
+ * 功能描述:RegisterDockPaneBll  
+ * 创 建 者:Garrett
+ * 创建日期:2017/9/28 15:47:34
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Internal.Windows;
+using Autodesk.Revit.UI;
+using Autodesk.Windows;
+using SAGA.RevitUtils.Extends;
+
+namespace SAGA.RevitMenu.Dockpane
+{
+    /// <summary>
+    /// RegisterDockPaneBll
+    /// </summary>
+    class StartSetting
+    {
+        /// <summary>
+        /// 不打开项目时,Ribbon默认展开
+        /// 注释掉,默认收起
+        /// </summary>
+        /// <param name="application"></param>
+        public static void RegiterPane(UIControlledApplication application)
+        {
+            //菜单显示
+            ComponentManager.Ribbon.AutoHideMode = RibbonAutoHideMode.None;
+            ComponentManager.Ribbon.ActiveTab =
+                ComponentManager.Ribbon.Tabs.FirstOrDefault();
+        }
+    }
+}

File diff suppressed because it is too large
+ 1473 - 0
SAGA.RevitMenu/ShortKey/KeyboardShortcuts.xml


+ 97 - 0
SAGA.RevitMenu/ShortKey/ScreenMenuKeyBoardShortCut.cs

@@ -0,0 +1,97 @@
+using System;
+using System.IO;
+using System.Xml;
+using SAGA.DotNetUtils;
+using SAGA.RevitMenu.ShortKey;
+using SAGA.RevitUtils;
+
+namespace SAGA.RevitMenu
+{
+    public class ScreenMenuKeyBoardShortCut
+    {
+        public static void SetKeyboardShortcuts(string versionName)
+        {
+            try
+            {
+                string path = Path.Combine(Path.Combine(Environment.ExpandEnvironmentVariables(@"%appdata%\Autodesk\Revit"), versionName), "KeyboardShortcuts.xml");
+                XmlDocument doc = new XmlDocument();
+                if (!File.Exists(path))
+                {
+                    File.Copy(
+                        Path.Combine(
+                            Path.Combine(AppBaseInfo.DllRunPath, "ShortKey"),
+                            "KeyboardShortcuts.xml"), path);
+                }
+
+                doc.Load(path);
+                SetSpaceShortcuts(doc);
+                doc.Save(path);
+            }
+            catch (Exception exception)
+            {
+                MessageShow.Show(exception, false, "");
+            }
+        }
+        /// <summary>
+        /// 设置放置空调的快捷键
+        /// </summary>
+        /// <param name="doc"></param>
+        private static void SetSpaceShortcuts(XmlDocument doc)
+        {
+            string SpaceKey = "UKJ";
+            string ASpaceKey = "UAKJ";
+            ShortKeyHelper.AddShotKey(doc, "ID_OBJECTS_MEP_SPACE", SpaceKey);
+            ShortKeyHelper.AddShotKey(doc, "Dialog_RoomAreaPlan_RoomTagDlgBar:Control_RoomAreaPlan_FindAllSpaces", ASpaceKey);
+
+            string SaveKey = "SSS";
+            ShortKeyHelper.AddShotKey(doc, "ID_REVIT_FILE_SAVE", SaveKey);
+        }
+
+        private static void SetOneKeyboardShortcuts(XmlDocument doc, string commandName, string className, string shortcuts, string ribbonTabName, string ribbonPanelName)
+        {
+            XmlElement documentElement = doc.DocumentElement;
+            string str = "CustomCtrl_%CustomCtrl_%" + ribbonTabName + "%" + ribbonPanelName + "%" + className;
+            string str2 = ribbonTabName + "&gt;" + ribbonPanelName;
+            string xpath = string.Format("Shortcuts/ShortcutItem[@CommandId='{0}']", str);
+            XmlNode node = doc.SelectSingleNode(xpath);
+            if (node == null)
+            {
+                XmlElement newChild = doc.CreateElement("ShortcutItem");
+                newChild.SetAttribute("CommandName", commandName);
+                newChild.SetAttribute("CommandId", str);
+                newChild.SetAttribute("Shortcuts", shortcuts);
+                newChild.SetAttribute("Paths", str2);
+                documentElement.AppendChild(newChild);
+            }
+            else
+            {
+                XmlElement element3 = node as XmlElement;
+                if (!element3.HasAttribute("Shortcuts"))
+                {
+                    element3.SetAttribute("Shortcuts", shortcuts);
+                }
+                else if (element3.GetAttribute("Shortcuts").CompareTo(shortcuts) != 0)
+                {
+                    element3.SetAttribute("Shortcuts", shortcuts);
+                }
+                if (!element3.HasAttribute("CommandName"))
+                {
+                    element3.SetAttribute("CommandName", commandName);
+                }
+                else if (element3.GetAttribute("CommandName").CompareTo(commandName) != 0)
+                {
+                    element3.SetAttribute("CommandName", commandName);
+                }
+                if (!element3.HasAttribute("Paths"))
+                {
+                    element3.SetAttribute("Paths", str2);
+                }
+                else if (element3.GetAttribute("Paths").CompareTo(str2) != 0)
+                {
+                    element3.SetAttribute("Paths", str2);
+                }
+            }
+        }
+    }
+}
+

+ 41 - 0
SAGA.RevitMenu/ShortKey/ShortKeyHelper.cs

@@ -0,0 +1,41 @@
+/* ==============================================================================
+ * 功能描述:ShortKeyHelper  
+ * 创 建 者:Garrett
+ * 创建日期:2017/11/30 16:25:19
+ * ==============================================================================*/
+
+using System.IO;
+using System.Linq;
+using System.Xml;
+using SAGA.DotNetUtils;
+
+namespace SAGA.RevitMenu.ShortKey
+{
+    /// <summary>
+    /// ShortKeyHelper
+    /// </summary>
+    public class ShortKeyHelper
+    {
+        public static void AddShotKey(XmlDocument doc ,string commandId, string key)
+        {
+            XmlNode xn = doc.SelectSingleNode($"/Shortcuts/ShortcutItem[@CommandId='{commandId}']");
+            string shortStr = "Shortcuts";
+            if (xn.Attributes[shortStr] == null)
+            {
+                XmlAttribute shorcutAttr=doc.CreateAttribute(shortStr);
+                shorcutAttr.Value = key;
+                xn.Attributes.Append(shorcutAttr);
+            }
+            else
+            {
+                var shortValue = xn.Attributes[shortStr].Value;
+                var shortArray = shortValue.Split('#');
+                if (!shortArray.Contains(key))
+                {
+                    shortValue += "#" + key;
+                }
+                xn.Attributes[shortStr].Value = shortValue;
+            }
+        }
+    }
+}

+ 26 - 0
SAGA.RevitMenu/TSZHideScreenMenuCmd.cs

@@ -0,0 +1,26 @@
+using SAGY.RevitMenu;
+
+namespace TSZ.RevitMenu
+{
+    using Autodesk.Revit.Attributes;
+    using Autodesk.Revit.DB;
+    using Autodesk.Revit.UI;
+    using System;
+    using TSZ.RevitBaseDll.Extends;
+
+    [Regeneration(RegenerationOption.Manual), Transaction(TransactionMode.Manual)]
+    public class TSZHideScreenMenuCmd : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
+            {
+                return Result.Cancelled;
+            }
+            Globals.HidePanels(commandData);
+            Globals.SaveState(false);
+            return Result.Succeeded;
+        }
+    }
+}
+

+ 24 - 0
SAGA.RevitMenu/TSZShowScreenMenuCmd.cs

@@ -0,0 +1,24 @@
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+
+namespace SAGY.RevitMenu
+{
+    [Regeneration(RegenerationOption.Manual), Transaction(TransactionMode.Manual)]
+    public class TSZShowScreenMenuCmd : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
+            {
+                return Result.Cancelled;
+            }
+            Globals.ExtCmdData = commandData;
+            Globals.ShowPanels(commandData);
+            Globals.SaveState(true);
+            ScreenMenuKeyBoardShortCut.SetKeyboardShortcuts(commandData.Application.Application.VersionName);
+            return Result.Succeeded;
+        }
+    }
+}
+

+ 96 - 0
ServiceMBI.sln

@@ -0,0 +1,96 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.3
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceMBI", "ServiceMBI\ServiceMBI.csproj", "{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAGA.RevitMenu", "SAGA.RevitMenu\SAGA.RevitMenu.csproj", "{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		R17|Any CPU = R17|Any CPU
+		R17|x64 = R17|x64
+		R17|x86 = R17|x86
+		R18|Any CPU = R18|Any CPU
+		R18|x64 = R18|x64
+		R18|x86 = R18|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+		RR17|Any CPU = RR17|Any CPU
+		RR17|x64 = RR17|x64
+		RR17|x86 = RR17|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Debug|x64.Build.0 = Debug|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Debug|x86.Build.0 = Debug|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R17|Any CPU.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R17|x64.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R17|x64.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R17|x86.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R17|x86.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R18|Any CPU.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R18|x64.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R18|x64.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R18|x86.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.R18|x86.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Release|x64.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Release|x64.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Release|x86.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.Release|x86.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.RR17|x64.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.RR17|x64.Build.0 = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.RR17|x86.ActiveCfg = Release|Any CPU
+		{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}.RR17|x86.Build.0 = Release|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Debug|x64.ActiveCfg = Debug|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Debug|x64.Build.0 = Debug|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Debug|x86.ActiveCfg = Debug|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Debug|x86.Build.0 = Debug|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R17|Any CPU.ActiveCfg = R17|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R17|Any CPU.Build.0 = R17|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R17|x64.ActiveCfg = R17|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R17|x64.Build.0 = R17|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R17|x86.ActiveCfg = R17|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R17|x86.Build.0 = R17|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R18|Any CPU.ActiveCfg = R18|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R18|Any CPU.Build.0 = R18|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R18|x64.ActiveCfg = R18|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R18|x64.Build.0 = R18|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R18|x86.ActiveCfg = R18|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.R18|x86.Build.0 = R18|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Release|x64.ActiveCfg = Release|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Release|x64.Build.0 = Release|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Release|x86.ActiveCfg = Release|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.Release|x86.Build.0 = Release|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|Any CPU.ActiveCfg = RR17|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|Any CPU.Build.0 = RR17|Any CPU
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x64.ActiveCfg = RR17|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x64.Build.0 = RR17|x64
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x86.ActiveCfg = RR17|x86
+		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x86.Build.0 = RR17|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {EF8DCEE9-4A1C-4EFD-A378-13ABCBBBA018}
+	EndGlobalSection
+EndGlobal

+ 6 - 0
ServiceMBI/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+    </startup>
+</configuration>

+ 51 - 0
ServiceMBI/Command.cs

@@ -0,0 +1,51 @@
+/* ==============================================================================
+ * 功能描述:Command  
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/11 12:01:04
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.UI;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+
+namespace ServiceMBI
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    [Transaction(TransactionMode.Manual)]
+    [Regeneration(RegenerationOption.Manual)]
+    public class Command : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            try
+            {
+                MessageShow.Infomation("Command Execute");
+
+            }
+            catch (Exception e)
+            {
+                MessageShow.Show(e);
+                return Result.Cancelled;
+            }
+            return Result.Succeeded;
+        }
+
+
+        /// <summary>
+        /// Onlys show the dialog when a document is open, as Dockable dialogs are only available
+        /// when a document is open.
+        /// </summary>
+        public override bool  IsCommandAvailable(UIApplication applicationData, CategorySet selectedCategories)
+        {
+            return true;
+        }
+    }
+}

+ 15 - 0
ServiceMBI/Program.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServiceMBI
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+        }
+    }
+}

+ 36 - 0
ServiceMBI/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("ServiceMBI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ServiceMBI")]
+[assembly: AssemblyCopyright("Copyright ©  2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("b57d1a6f-dca8-4122-bd69-0eb97f7371ea")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 68 - 0
ServiceMBI/ServiceMBI.csproj

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{B57D1A6F-DCA8-4122-BD69-0EB97F7371EA}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>ServiceMBI</RootNamespace>
+    <AssemblyName>ServiceMBI</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="RevitAPI">
+      <HintPath>..\Dlls\RevitRefDll\RevitAPI.dll</HintPath>
+    </Reference>
+    <Reference Include="RevitAPIUI">
+      <HintPath>..\Dlls\RevitRefDll\RevitAPIUI.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.DotNetUtils">
+      <HintPath>..\Dlls\SAGA.DotNetUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.RevitUtils">
+      <HintPath>..\Dlls\SAGA.RevitUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Command.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>