乐筑天下

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

可自动注册dll的另类实现

[复制链接]

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-7-8 14:46:00 | 显示全部楼层 |阅读模式
看过kean的相关主题,对自动注册dll的方式应该都不会太陌生
方法是在程序载入时检查注册表项,如果没有就添加
不过这种方式的弊病是必须在代码中调用自动注册类的相关函数,那么有没有更简单的方式?

我们知道,自动注册dll是在继承IExtensionApplication接口的类的Initialize例程中完成的,那么Cad在遇到这种类就会首先实例化该类,并在载入时运行这个Initialize例程,下面的想法就是利用这一点,在类实例化时自动检查

基类:AutoRegAssem

SerialList在这里

InvokeArx在这里
  1. using Microsoft.Win32;
  2. using System;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Resources;
  6. using System.Reflection;
  7. using System.Collections.Generic;
  8. using System.Text.RegularExpressions;
  9. using Autodesk..Runtime;
  10. using Autodesk.AutoCAD.EditorInput;
  11. using Autodesk.AutoCAD.DatabaseServices;
  12. using Autodesk.AutoCAD.ApplicationServices;
  13. using TlsCad.Utils;
  14. using TlsCad.Collections;
  15. [assembly: CommandClass(typeof(TlsCad.Trans.AutoRegAssem))]
  16. namespace TlsCad.Trans
  17. {
  18.     [Serializable]
  19.     public class AutoRegAssem : SerialList
  20.     {
  21.         private string _infoFileName = null;
  22.         private static List _regApps;
  23.         private static List _assems = new List();
  24.         public Assembly Assembly
  25.         { private set; get; }
  26.         public static AutoRegAssem CurrAssem
  27.         {
  28.             get
  29.             {
  30.                 Assembly assembly = Assembly.GetCallingAssembly();
  31.                 return
  32.                     _assems.Find(
  33.                         assem =>
  34.                         assem.Assembly == assembly);
  35.             }
  36.         }
  37.         protected virtual AssemLoadType LoadType
  38.         {
  39.             get
  40.             {
  41.                 return AssemLoadType.Startting;
  42.             }
  43.         }
  44.         public static string Location
  45.         {
  46.             get
  47.             {
  48.                 return Assembly.GetCallingAssembly().Location;
  49.             }
  50.         }
  51.         public static DirectoryInfo Directory
  52.         {
  53.             get
  54.             {
  55.                 return new DirectoryInfo(Location).Parent;
  56.             }
  57.         }
  58.         public AutoRegAssem()
  59.         {
  60.             Assembly = Assembly.GetCallingAssembly();
  61.             Info.Loader = Assembly.Location;
  62.             Info.Fullname = Assembly.FullName;
  63.             Info.Name = Assembly.GetName().Name;
  64.             Info.LoadType = LoadType;
  65.             _infoFileName =
  66.                 new DirectoryInfo(Assembly.Location).Parent.FullName;
  67.             if (_infoFileName.LastIndexOf("") != _infoFileName.Length - 1)
  68.                 _infoFileName += "";
  69.             _infoFileName += Info.Name + ".assx";
  70.             if (!File.Exists(_infoFileName))
  71.             {
  72.                 GetInfoFromAssembly();
  73.                 WriteXml(_infoFileName);
  74.             }
  75.             else
  76.             {
  77.                 GetInfoFromFile();
  78.             }
  79.             if (!SearchForReg())
  80.             {
  81.                 RegApp();
  82.             }
  83.             _assems.Add(this);
  84.         }
  85.         
  86.         #region LoadAndSave
  87.         private void GetInfoFromFile()
  88.         {
  89.             ReadXml(_infoFileName);
  90.             this.Sort();
  91.         }
  92.         private bool GetInfoFromAssembly()
  93.         {
  94.             List cmds = new List();
  95.             try
  96.             {
  97.                 Info.Fullname = Assembly.FullName;
  98.                 foreach (Module m in Assembly.GetModules(true))
  99.                 {
  100.                     Type[] types = m.GetTypes();
  101.                     foreach (Type t in types)
  102.                     {
  103.                         ResourceManager rm =
  104.                             new ResourceManager(t.FullName, Assembly);
  105.                         rm.IgnoreCase = true;
  106.                         MethodInfo[] methods = t.GetMethods();
  107.                         foreach (MethodInfo mi in methods)
  108.                         {
  109.                             object[] attbs =
  110.                                 mi.GetCustomAttributes(
  111.                                     typeof(CommandMethodAttribute),
  112.                                     true
  113.                                 );
  114.                             foreach (object attb in attbs)
  115.                             {
  116.                                 CommandMethodAttribute cma = attb as CommandMethodAttribute;
  117.                                 if (cma != null)
  118.                                 {
  119.                                     Command cmd = new Command(cma.GlobalName);
  120.                                     if (cma.GroupName != null)
  121.                                     {
  122.                                         cmd.GroupName = cma.GroupName;
  123.                                     }
  124.                                     cmd.TypeName = t.FullName;
  125.                                     cmd.MethodName = mi.Name;
  126.                                     cmd.LocalizedName = cmd.GlobalName;
  127.                                     string lnid = cma.LocalizedNameId;
  128.                                     if (lnid != null)
  129.                                     {
  130.                                         try
  131.                                         {
  132.                                             cmd.LocalizedName = rm.GetString(lnid);
  133.                                         }
  134.                                         catch
  135.                                         { }
  136.                                     }
  137.                                     cmds.Add(cmd);
  138.                                 }                            }
  139.                         }
  140.                     }
  141.                 }
  142.                 AddRange(cmds);
  143.                 return true;
  144.             }
  145.             catch (System.Exception ex)
  146.             {
  147.                 throw ex;
  148.             }        }
  149.         #endregion
  150.         #region Reg
  151.         private RegistryKey GetAcAppKey()
  152.         {
  153.             RegistryKey ackey =
  154.                 Registry.CurrentUser.OpenSubKey(
  155.                     HostApplicationServices.Current.RegistryProductRootKey, true);
  156.             return ackey.CreateSubKey("Applications");
  157.         }
  158.         private bool SearchForReg()
  159.         {
  160.             if (_regApps == null)
  161.             {
  162.                 RegistryKey appkey = GetAcAppKey();
  163.                 _regApps = new List(appkey.GetSubKeyNames());
  164.                 appkey.Close();
  165.             }
  166.             bool find = _regApps.Contains(Info.Name);
  167.             if (!find)
  168.             {
  169.                 _regApps.Add(Info.Name);
  170.             }
  171.             return find;
  172.         }
  173.         public void RegApp()
  174.         {
  175.             RegistryKey appkey = GetAcAppKey();
  176.             RegistryKey rk = appkey.CreateSubKey(Info.Name);
  177.             rk.SetValue("DESCRIPTION", Info.Fullname, RegistryValueKind.String);
  178.             rk.SetValue("LOADCTRLS", Info.LoadType, RegistryValueKind.DWord);
  179.             rk.SetValue("LOADER", Info.Loader, RegistryValueKind.String);
  180.             rk.SetValue("MANAGED", 1, RegistryValueKind.DWord);
  181.             RegistryKey cmdrk = rk.CreateSubKey("Commands");
  182.             foreach (Command cmd in this)
  183.             {
  184.                 cmdrk.SetValue(cmd.GlobalName, cmd.GlobalName, RegistryValueKind.String);
  185.             }
  186.             var groups =
  187.                 from cmd in this
  188.                 where cmd.GroupName != null
  189.                 select cmd.GroupName;
  190.             RegistryKey grprk = rk.CreateSubKey("Groups");
  191.             foreach (string g in groups.Distinct())
  192.             {
  193.                 grprk.SetValue(g, g, RegistryValueKind.String);
  194.             }
  195.             appkey.Close();
  196.         }
  197.         public void UnRegApp()
  198.         {
  199.             using (RegistryKey appkey = GetAcAppKey())
  200.             {
  201.                 DeleteSubKey(appkey, Info.Name);
  202.             }
  203.         }
  204.         private void DeleteSubKey(RegistryKey parent, params string[] subNames)
  205.         {
  206.             foreach (string name in subNames)
  207.             {
  208.                 RegistryKey rk = parent.OpenSubKey(name, true);
  209.                 DeleteSubKey(rk, rk.GetSubKeyNames());
  210.                 parent.DeleteSubKey(name);
  211.             }
  212.         }
  213.         [CommandMethod("NetUnReg")]
  214.         public static void NetUnReg()
  215.         {
  216.             Document doc = Application.DocumentManager.MdiActiveDocument;
  217.             Editor ed = doc.Editor;            ed.WriteMessage("\n欢迎使用TlsCad.Net程序注册表卸载!\n请从下面的序号中选择需要卸载的程序:(多项选择用逗号分隔)");
  218.             if (_assems.Count == 0)
  219.             {
  220.                 ed.WriteMessage("\n没有需要卸载的程序!");
  221.                 return;
  222.             }
  223.             InvokeArx.DisplayTextScreen = true;
  224.             int i = 0;
  225.             foreach (AutoRegAssem assem in _assems)
  226.             {
  227.                 ed.WriteMessage("\n{0}.{1}", ++i, assem.Info.Name);
  228.             }
  229.             var resStr = ed.GetString("\n请输入序号:");
  230.             do
  231.             {
  232.                 if (resStr.Status == PromptStatus.OK)
  233.                 {
  234.                     string str = resStr.StringResult;
  235.                     if (!Regex.IsMatch(str, @"^\d*[,\d]*\d$"))
  236.                     {
  237.                         ed.WriteMessage("\n格式错误!");
  238.                     }
  239.                     else
  240.                     {
  241.                         var ids = str.Split(',').Select(s => Convert.ToInt32(s) - 1).ToList();
  242.                         if (ids.Any(id => id >= 0 && id  _assems[id]).ToList();
  243.                             var nassems = new List();
  244.                             foreach (var assem in assems)
  245.                             {
  246.                                 var opts =
  247.                                     new PromptKeywordOptions("\n是否删除" + assem.Info.Name);
  248.                                 opts.Keywords.Add("Yes");
  249.                                 opts.Keywords.Add("No");
  250.                                 opts.Keywords.Default = "No";
  251.                                 var resKey = ed.GetKeywords(opts);
  252.                                 if (resKey.Status == PromptStatus.Cancel)
  253.                                     return;
  254.                                 else if (resKey.Status != PromptStatus.OK || resKey.StringResult == "No")
  255.                                     nassems.Add(assem);
  256.                             }
  257.                             assems = assems.Except(nassems).ToList();
  258.                             assems.ForEach(assem => assem.UnRegApp());
  259.                             _assems = _assems.Except(assems).ToList();
  260.                             break;
  261.                         }
  262.                         ed.WriteMessage("\n数字超出范围!");
  263.                     }
  264.                 }
  265.                 resStr = ed.GetString("\n请重新输入序号:");
  266.             } while (resStr.Status != PromptStatus.Cancel);
  267.             InvokeArx.DisplayTextScreen = false;        }
  268.         #endregion
  269.         #region RunCommand(Test)
  270.         public void Run(Command cmd)
  271.         {
  272.             if (Assembly == null)
  273.             {
  274.                 Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  275.                 foreach (Assembly assembly in assemblys)
  276.                 {
  277.                     if (assembly.FullName == Info.Fullname)
  278.                     {
  279.                         Assembly = assembly;
  280.                         break;
  281.                     }
  282.                 }
  283.             }
  284.             if (Assembly != null)
  285.             {
  286.                 Type t = Assembly.GetType(cmd.TypeName);
  287.                 object obj = Assembly.CreateInstance(t.FullName);
  288.                 MethodInfo mi = t.GetMethod(cmd.MethodName);
  289.                 mi.Invoke(obj, new object[0]);
  290.                 obj = null;
  291.             }
  292.         }
  293.         #endregion
  294.     }
  295. }

回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-7-8 14:48:00 | 显示全部楼层
相关类

Command
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace TlsCad.Trans
  6. {
  7.     [Serializable]
  8.     public class Command : IComparable
  9.     {
  10.         public string GlobalName;
  11.         public string LocalizedName;
  12.         public string GroupName;
  13.         public string TypeName;
  14.         public string MethodName;
  15.         public string Description;
  16.         public Command() { }
  17.         public Command(string globalName)
  18.         {
  19.             GlobalName = globalName;
  20.         }
  21.         #region IComparable 成员
  22.         int IComparable.CompareTo(Command other)
  23.         {
  24.             return this.GlobalName.CompareTo(other.GlobalName);
  25.         }
  26.         #endregion
  27.     }
  28. }

AssemInfo
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace TlsCad.Trans
  6. {
  7.     public enum AssemLoadType
  8.     {
  9.         Startting = 2,
  10.         ByCommand = 12,
  11.         Disabled = 20
  12.     }
  13.     [Serializable]
  14.     public struct AssemInfo
  15.     {
  16.         ///
  17.         /// 注册名
  18.         ///
  19.         public string Name;
  20.         ///
  21.         /// 程序集全名
  22.         ///
  23.         public string Fullname;
  24.         ///
  25.         /// 程序集路径
  26.         ///
  27.         public string Loader;
  28.         ///
  29.         /// 加载方式
  30.         ///
  31.         public AssemLoadType LoadType;
  32.         ///
  33.         /// 程序集说明
  34.         ///
  35.         public string Description;
  36.     }
  37. }


回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-7-8 14:54:00 | 显示全部楼层

调用的方式:
把上面的类放在一个类库里,或者放在你的内库里:),编译为dll

在你需要自动注册的工程里引用上面的类库
然后:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using TlsCad.Trans;
  6. using Autodesk.AutoCAD.Runtime;
  7. [assembly: ExtensionApplication(typeof(TlsTest.MyApp))]
  8. namespace TlsTest
  9. {    public class MyApp : AutoRegAssem, IExtensionApplication
  10.     {
  11.         #region IExtensionApplication 成员
  12.         void IExtensionApplication.Initialize()
  13.         {
  14.         }
  15.         void IExtensionApplication.Terminate()
  16.         {
  17.         }
  18.         #endregion
  19.     }
  20. }

回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-7-8 15:47:00 | 显示全部楼层
同时在基类中封装了两个获取当前dll路径的属性
调用方式:复制代码
回复

使用道具 举报

110

主题

324

帖子

10

银币

中流砥柱

Rank: 25

铜币
764
发表于 2010-8-29 15:38:00 | 显示全部楼层
顶!!!!!!
回复

使用道具 举报

0

主题

23

帖子

2

银币

初来乍到

Rank: 1

铜币
23
发表于 2011-11-8 17:08:00 | 显示全部楼层
Mark,follows!
回复

使用道具 举报

54

主题

552

帖子

11

银币

中流砥柱

Rank: 25

铜币
767
发表于 2012-9-24 15:43:00 | 显示全部楼层
曲高和寡啊,高山仰止
回复

使用道具 举报

0

主题

7

帖子

3

银币

初来乍到

Rank: 1

铜币
7
发表于 2012-10-14 17:55:00 | 显示全部楼层
这个很有用,谢谢了
回复

使用道具 举报

2

主题

7

帖子

1

银币

初来乍到

Rank: 1

铜币
15
发表于 2015-4-25 16:07:00 | 显示全部楼层
最近正在找这个资料,非常感谢
回复

使用道具 举报

110

主题

324

帖子

10

银币

中流砥柱

Rank: 25

铜币
764
发表于 2015-4-28 16:16:00 | 显示全部楼层
顶!!!!!!!!!!!
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2025-6-28 18:54 , Processed in 1.266942 second(s), 73 queries .

© 2020-2025 乐筑天下

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