乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 70|回复: 1

利用反射加载注册表和添加菜单

[复制链接]

3

主题

21

帖子

2

银币

初来乍到

Rank: 1

铜币
33
发表于 2019-3-17 13:43:00 | 显示全部楼层 |阅读模式
程序的注册表写到HKLM下,所以第一次加载需要用管理员权限打开cad。
主要函数:
1# ====
  '''
    ''' 提取当前程序集所有注册的命令信息
    '''
    '''
    Private Shared Function GetCueentAssemblyCmd() As Dictionary(Of String, List(Of String()))
        Dim listCmd As Dictionary(Of String, List(Of String())) = New Dictionary(Of String, List(Of String()))
        Dim currentAss = Assembly.GetExecutingAssembly()
        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
        'ed.WriteMessage(currentAss.FullName + Environment.NewLine)
        For Each typeItem As Type In currentAss.GetTypes()
            If typeItem.IsClass And typeItem.IsPublic Then
                For Each method As MethodInfo In typeItem.GetMethods()
                    If method.IsPublic And method.GetCustomAttributes(True).Length > 0 Then
                        For Each att As Object In method.GetCustomAttributes(True)
                            If att.GetType().Name = GetType(CommandMethodAttribute).Name Then
                                Dim att_CommandMethod As CommandMethodAttribute = att
                                If listCmd.ContainsKey(typeItem.Name) Then
                                    Dim dicTemp = listCmd(typeItem.Name)
                                    dicTemp.Add(New String() {method.Name, att_CommandMethod.GlobalName})
                                    listCmd(typeItem.Name) = dicTemp
                                Else
                                    Dim listTemp As List(Of String()) = New List(Of String())
                                    listTemp.Add(New String() {method.Name, att_CommandMethod.GlobalName})
                                    listCmd(typeItem.Name) = listTemp
                                End If
                            End If
                        Next
                    End If
                Next
            End If
        Next
        Return listCmd
    End Function
2#
'''
    ''' 将自定义的命令组合成菜单的形式
    '''
    '''
    Private Shared Sub AddMenuBartoAutoCAD(listCmd As Dictionary(Of String, List(Of String())))
        Dim acadApp As AcadApplication = Application.AcadApplication
        Dim currentAssName = Assembly.GetExecutingAssembly().ManifestModule.Name.Substring(0, Assembly.GetExecutingAssembly().ManifestModule.Name.Length - 4)
        For index = 0 To acadApp.MenuGroups.Item(0).Menus.Count - 1
            Dim mg As AcadPopupMenu = acadApp.MenuGroups.Item(0).Menus.Item(index)
            If mg.Name = currentAssName Then acadApp.MenuGroups.Item(0).Menus.Item(index).RemoveFromMenuBar()
        Next
        Dim mg_menuBar As AcadPopupMenu = acadApp.MenuGroups.Item(0).Menus.Add(currentAssName)
        For Each item As KeyValuePair(Of String, List(Of String())) In listCmd
            Dim submenu = mg_menuBar.AddSubMenu(mg_menuBar.Count + 1, item.Key)
            For Each cmd As String() In item.Value
                submenu.AddMenuItem(submenu.Count + 1, cmd(0), cmd(1) + " ")
            Next
        Next
        mg_menuBar.InsertInMenuBar(acadApp.MenuBar.Count + 1)
    End Sub
3#
'''
    ''' 写入注册表到HKLM
    '''
    Private Shared Sub DllAutoLoader()
        Dim regPath As String = HostApplicationServices.Current.RegistryProductRootKey.Replace("Software", "SOFTWARE") 'Software\Autodesk\AutoCAD\R18.0\ACAD-8001:804
        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
        Dim assName = Assembly.GetExecutingAssembly().CodeBase
        Dim apps_Acad = Registry.LocalMachine.OpenSubKey(Path.Combine(regPath, "Applications"), False)
        Dim counts = apps_Acad.SubKeyCount, flag As Boolean = False
        For Each item As String In apps_Acad.GetSubKeyNames()
            If item = Path.GetFileNameWithoutExtension(assName) Then flag = True
        Next
        If flag = False Then
            Dim autocad_App As RegistryKey
            autocad_App = Registry.LocalMachine.OpenSubKey(Path.Combine(regPath, "Applications"), True) 'RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl
            Dim myNerLoader = autocad_App.CreateSubKey(Path.GetFileNameWithoutExtension(assName), RegistryKeyPermissionCheck.Default)
            myNerLoader.SetValue("DESCRIPTION", "加载自定义dll文件", Microsoft.Win32.RegistryValueKind.String)
            myNerLoader.SetValue("LOADCTRLS", 2, Microsoft.Win32.RegistryValueKind.DWord)
            myNerLoader.SetValue("LOADER", assName, Microsoft.Win32.RegistryValueKind.String)
            myNerLoader.SetValue("MANAGED", 1, Microsoft.Win32.RegistryValueKind.DWord)
            Application.ShowAlertDialog(Path.GetFileNameWithoutExtension(assName) + "程序自动加载完成,重启AutoCAD 生效!")
        Else
            Application.ShowAlertDialog(Path.GetFileNameWithoutExtension(assName) + "程序已经启动!欢迎使用")
        End If
    End Sub
4# 利用初始
Public Class MainClass
    Implements IExtensionApplication
    Public Sub Initialize() Implements IExtensionApplication.Initialize
        Dim listCmd As Dictionary(Of String, List(Of String())) = GetCueentAssemblyCmd()
        Call DllAutoLoader() 'Dll  自动加载设置
        Call AddMenuBartoAutoCAD(listCmd) '利用反射插入菜单
    End Sub
end class

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

3

主题

21

帖子

2

银币

初来乍到

Rank: 1

铜币
33
发表于 2019-4-27 09:12:00 | 显示全部楼层
之前的menubar菜单对跨版本还是有限制,主要是com对象的前期绑定导致的。后期绑定有好麻烦。
采用ribbon选项卡和面板可以实现跨版本使用。大家不惜勿喷,主要为了适应跨版本,目前公司有买了2017,2019等,原来的2015也有保留。
1# 先定义一个特性
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace AutoCADRibbon
  7. {
  8.     public class CmdHelperAttribute : Attribute
  9.     {
  10.         public string HelpContent { get; set; }
  11.         public string IcoFileName { get; set; }
  12.         // This is a positional argument
  13.         public CmdHelperAttribute(string _HelpString,string imageFilePath)
  14.         {
  15.             this.HelpContent = _HelpString;
  16.             this.IcoFileName = imageFilePath;
  17.         }
  18.     }
  19. }
2# 在autocad 注册命令的是否添加图标和帮助信息中
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.Runtime;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace AutoCADRibbon
  11. {
  12.    public  class classFunction1
  13.     {
  14.         [CmdHelper("mto套料程序kkkkkkk","1.ico")]
  15.         [CommandMethod("mymto")]
  16.         public void mto套料()
  17.         {
  18.             Application.ShowAlertDialog("mto套料程序");
  19.         }
  20.         [CmdHelper("mto套料程序2jjjjjj", "3.ico")]
  21.         [CommandMethod("mymto2")]
  22.         public void mto套料2()
  23.         {
  24.             Application.ShowAlertDialog("mto套料程序8");
  25.         }
  26.         [CmdHelper("mto套料程序8jjjjjj", "3.ico")]
  27.         [CommandMethod("mymto8")]
  28.         public void mto套料8()
  29.         {
  30.             Application.ShowAlertDialog("mto套料程序8");
  31.         }
  32.     }
  33.     public class classFunction2
  34.     {
  35.         [CmdHelper("mto套料程序3jjjjjjj", "3.ico")]
  36.         [CommandMethod("mymto3")]
  37.         public void mto套料3()
  38.         {
  39.             Application.ShowAlertDialog("mto套料程序3");
  40.         }
  41.         [CmdHelper("mto套料程序41111111", "2.ico")]
  42.         [CommandMethod("mymto4")]
  43.         public void mto套料4()
  44.         {
  45.             Application.ShowAlertDialog("mto套料程序4");
  46.         }
  47.     }
  48.     public class classFunction3
  49.     {
  50.         [CmdHelper("mto套料程序5jjjjjjj", "1.ico")]
  51.         [CommandMethod("mymto5")]
  52.         public void mto套料5()
  53.         {
  54.             Application.ShowAlertDialog("mto套料程序5");
  55.         }
  56.         [CmdHelper("mto套料程序61111111", "2.ico")]
  57.         [CommandMethod("mymto6")]
  58.         public void mto套料6()
  59.         {
  60.             Application.ShowAlertDialog("mto套料程序6");
  61.         }
  62.     }
  63. }

3# 在程序启动是检测riibon的受否打开以及是否加载完毕
  1. public class MainClass : IExtensionApplication
  2.     {
  3.         public void Initialize()
  4.         {
  5.             helper.Register2HKCR();
  6.             Autodesk.Windows.ComponentManager.ItemInitialized += ComponentManager_ItemInitialized;
  7.         }
  8.         private void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
  9.         {
  10.             if (Autodesk.Windows.ComponentManager.Ribbon == null)
  11.             {//如果Ribbon没有打开,直接操作命令行打开
  12.                 Application.DocumentManager.MdiActiveDocument.SendStringToExecute("_.ribbon\r", true, false, false);
  13.             }
  14.             else
  15.             {
  16.                 var cmd = helper.GetDllCmds(Assembly.GetExecutingAssembly().Location);
  17.                 helper.AddCmdtoRibbon(cmd);
  18.                 Autodesk.Windows.ComponentManager.ItemInitialized -= ComponentManager_ItemInitialized;
  19.             }
  20.         }
  21.         public void Terminate()
  22.         {
  23.             throw new NotImplementedException();
  24.         }
  25.     }

4#创建一些帮助类
  1. //为ribbon菜单指派事件
  2.     public class AdskCommonHandler : System.Windows.Input.ICommand
  3.     {
  4.         public event EventHandler CanExecuteChanged;
  5.         public bool CanExecute(object parameter)
  6.         {
  7.             return true;
  8.         }
  9.         public void Execute(object parameter)
  10.         {
  11.             RibbonButton button = parameter as RibbonButton;
  12.             if (button == null || button.CommandParameter == null) return;
  13.             Application.DocumentManager.MdiActiveDocument.SendStringToExecute((string)button.CommandParameter + " ", true, false, true);
  14.         }
  15.     }
  16.     public static class helper
  17.     {///
  18.      ///提取所有的命令
  19.      ///
  20.      /// dll的路径
  21.      ///
  22.         public static List GetDllCmds(params string[] dllFiles)
  23.         {
  24.             List res = new List();
  25.             List cmds = new List();
  26.             #region 提取所以的命令
  27.             for (int i = 0; i  t.IsClass && t.IsPublic).ToList();
  28.                 if (clsCollection.Count > 0)
  29.                 {
  30.                     foreach (var cls in clsCollection)
  31.                     {
  32.                         var methods = cls.GetMethods().Where(m => m.IsPublic && m.GetCustomAttributes(true).Length > 0).ToList();
  33.                         if (methods.Count > 0)
  34.                         {
  35.                             foreach (MethodInfo mi in methods)
  36.                             {
  37.                                 var atts_CmdString = mi.GetCustomAttributes(true).Where(c => c is CommandMethodAttribute).ToList();
  38.                                 var atts_HelpString = mi.GetCustomAttributes(true).Where(c => c is CmdHelperAttribute).ToList();
  39.                                 if (atts_CmdString.Count == 1 && atts_HelpString.Count == 1)
  40.                                 {
  41.                                     gcadCmds cmd = new gcadCmds(cls.Name, mi.Name, (atts_CmdString[0] as CommandMethodAttribute).GlobalName,
  42.                                         ass.ManifestModule.Name.Substring(0, ass.ManifestModule.Name.Length - 4), (atts_HelpString[0] as CmdHelperAttribute).HelpContent, (atts_HelpString[0] as CmdHelperAttribute).IcoFileName);
  43.                                     cmds.Add(cmd);
  44.                                 }
  45.                             }
  46.                         }
  47.                     }
  48.                 }
  49.             }
  50.             #endregion
  51.             if (cmds.Count > 0)
  52.             {
  53.                 List dllName = new List();
  54.                 foreach (var item in cmds) if (!dllName.Contains(item.dllName)) dllName.Add(item.dllName);
  55.                 foreach (var item in dllName) res.Add(new gcadDllcmd(item, cmds));
  56.             }
  57.             return res;
  58.             //
  59.         }
  60.         public static void AddCmdtoRibbon(List cmds)
  61.         {
  62.             RibbonControl ribbon = ComponentManager.Ribbon;
  63.             if (ribbon != null)
  64.             {
  65.                 foreach (var dll in cmds)
  66.                 {
  67.                     RibbonTab rtab = ribbon.FindTab(dll.DllName);
  68.                     if (rtab != null) ribbon.Tabs.Remove(rtab);
  69.                     rtab = new RibbonTab()
  70.                     {
  71.                         Title = dll.DllName,
  72.                         Id = dll.DllName,
  73.                         IsVisible = true
  74.                     };
  75.                     //Add the Tab
  76.                     ribbon.Tabs.Add(rtab);
  77.                     //added the panels
  78.                     foreach (var item in dll.clsCmds)
  79.                     {
  80.                         RibbonPanelSource rps = new RibbonPanelSource() { Title = item.clsName };
  81.                         RibbonPanel rp = new RibbonPanel()
  82.                         {
  83.                             Source = rps,
  84.                             IsVisible = true,
  85.                             ResizeStyle = RibbonResizeStyles.NeverHideText,
  86.                             AnimationMode = Autodesk.Internal.Windows.RibbonPanelAnimationMode.None
  87.                         };
  88.                         RibbonSubPanelSource psps = new RibbonSubPanelSource() { Name = item.clsName, Id = item.clsName };
  89.                         RibbonRowPanel rrp = new RibbonRowPanel()
  90.                         {
  91.                             Source = psps,
  92.                             IsEnabled = true,
  93.                             IsVisible = true,
  94.                             SubPanelResizeStyle = RibbonRowPanelResizeStyle.NeverHideText,
  95.                             ResizeStyle = RibbonItemResizeStyles.ResizeWidth
  96.                         };
  97.                         //int i = 0;
  98.                         foreach (var clsCmd in item.curClscmds)
  99.                         {
  100.                             RibbonButton rb = new RibbonButton()
  101.                             {
  102.                                 Text = clsCmd.cmdName,
  103.                                 ShowText = true,
  104.                                 ShowImage = true,
  105.                                 AllowInToolBar = true,
  106.                                 AllowInStatusBar = true,
  107.                                 Description = clsCmd.HelpeText,
  108.                                 Orientation = System.Windows.Controls.Orientation.Vertical,
  109.                                 CommandParameter = clsCmd.cmdMacro
  110.                             };
  111.                             if (File.Exists(clsCmd.IcnoName))
  112.                             {
  113.                                 rb.Image = Images.getBitmap(new Bitmap(clsCmd.IcnoName));
  114.                                 rb.Size = RibbonItemSize.Large;
  115.                                 rb.LargeImage = Images.getBitmap(new Bitmap(clsCmd.IcnoName));
  116.                             }
  117.                             rb.CommandHandler = new AdskCommonHandler();
  118.                             psps.Items.Add(rb);
  119.                             //i++;
  120.                             //if (i >= 2)
  121.                             //{
  122.                             //    rps.Items.Add(new RibbonPanelBreak() { IsVisible = true });
  123.                             //    i = 0;
  124.                             //}
  125.                         }
  126.                         rps.Items.Add(rrp);
  127.                         rtab.Panels.Add(rp);
  128.                     }
  129.                 }
  130.             }
  131.         }
  132.         ///
  133.         /// 将菜单加载到AutoCAD
  134.         ///
  135.         public static void Register2HKCR()
  136.         {
  137.             string hkcrKey = HostApplicationServices.Current.UserRegistryProductRootKey;
  138.             var assName = Assembly.GetExecutingAssembly().CodeBase;
  139.             var apps_Acad = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(Path.Combine(hkcrKey, "Applications"));
  140.             if (apps_Acad.GetSubKeyNames().Count(c => c == Path.GetFileNameWithoutExtension(assName)) == 0)
  141.             {
  142.                 var myNetLoader = apps_Acad.CreateSubKey(Path.GetFileNameWithoutExtension(assName), RegistryKeyPermissionCheck.Default);
  143.                 myNetLoader.SetValue("DESCRIPTION", "加载自定义dll文件", Microsoft.Win32.RegistryValueKind.String);
  144.                 myNetLoader.SetValue("LOADCTRLS", 2, Microsoft.Win32.RegistryValueKind.DWord);
  145.                 myNetLoader.SetValue("LOADER", assName, Microsoft.Win32.RegistryValueKind.String);
  146.                 myNetLoader.SetValue("MANAGED", 1, Microsoft.Win32.RegistryValueKind.DWord);
  147.                 Application.ShowAlertDialog(Path.GetFileNameWithoutExtension(assName) + "程序加载成功!欢迎使用");
  148.             }
  149.         }
  150.         public class gcadCmds
  151.         {
  152.             public string clsName { get; set; }
  153.             public string cmdName { get; set; }
  154.             public string cmdMacro { get; set; }
  155.             public string dllName { get; set; }
  156.             public string HelpeText { get; set; }
  157.             public string IcnoName { get; set; }
  158.             public gcadCmds(string _clsName, string _cmdName, string _macro, string _dllName, string _helperText, string _iamgeName)
  159.             {
  160.                 this.dllName = _dllName;
  161.                 this.clsName = _clsName;
  162.                 this.cmdMacro = _macro;
  163.                 this.cmdName = _cmdName;
  164.                 this.HelpeText = _helperText;
  165.                 this.IcnoName = _iamgeName;
  166.             }
  167.         }
  168.         ///
  169.         /// 储存包含自定命令的类
  170.         ///
  171.         public class gcadClscmd
  172.         {
  173.             public string clsName { get; set; }
  174.             public string dllName { get; set; }
  175.             public bool HasGcadcmds { get; set; }
  176.             public List curClscmds { get; set; }
  177.             public gcadClscmd(string _clsName, List cmds)
  178.             {
  179.                 this.clsName = _clsName;
  180.                 this.dllName = cmds.First().dllName;
  181.                 var clsCmds = cmds.Where(c => c.clsName == this.clsName).ToList();
  182.                 if (clsCmds.Count > 0)
  183.                 {
  184.                     this.HasGcadcmds = true;
  185.                     this.curClscmds = new List();
  186.                     foreach (var item in clsCmds)
  187.                     {
  188.                         if (item.clsName == this.clsName) this.curClscmds.Add(item);
  189.                     }
  190.                 }
  191.                 else this.HasGcadcmds = false;
  192.             }
  193.         }
  194.         ///
  195.         /// 储存每个dll类的
  196.         ///
  197.         public class gcadDllcmd
  198.         {
  199.             public string DllName { get; set; }
  200.             public bool HasGcadcls { get; set; }
  201.             public List clsCmds { get; set; }
  202.             public List curDllcmds { get; set; }
  203.             public gcadDllcmd(string _dllname, List cmds)
  204.             {
  205.                 this.DllName = _dllname;
  206.                 var curDllcmds = cmds.Where(c => c.dllName == this.DllName).ToList();
  207.                 if (curDllcmds.Count > 0)
  208.                 {
  209.                     this.HasGcadcls = true;
  210.                     this.curDllcmds = curDllcmds;
  211.                     List listClsName = new List();
  212.                     foreach (gcadCmds item in this.curDllcmds)
  213.                     {
  214.                         if (!listClsName.Contains(item.clsName)) listClsName.Add(item.clsName);
  215.                     }
  216.                     this.clsCmds = new List();
  217.                     foreach (var item in listClsName)
  218.                     {
  219.                         gcadClscmd clsCmds = new gcadClscmd(item, this.curDllcmds.Where(c => c.clsName == item).ToList());
  220.                         this.clsCmds.Add(clsCmds);
  221.                     }
  222.                 }
  223.                 else this.HasGcadcls = false;
  224.             }
  225.         }
  226.         public class Images
  227.         {
  228.             public static BitmapImage getBitmap(Bitmap image)
  229.             {
  230.                 MemoryStream stream = new MemoryStream();
  231.                 image.Save(stream, ImageFormat.Png);
  232.                 BitmapImage bmp = new BitmapImage();
  233.                 bmp.BeginInit();
  234.                 bmp.StreamSource = stream;
  235.                 bmp.EndInit();
  236.                 return bmp;
  237.             }
  238.         }
  239.     }

回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-13 02:30 , Processed in 0.716492 second(s), 61 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表