知识大全 深入解析.NET 许可证编译器 (Lc.exe) 的原理与源代码剖析

Posted 文件

篇首语:成年人的平和,一半是理解,一半是算了。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 深入解析.NET 许可证编译器 (Lc.exe) 的原理与源代码剖析相关的知识,希望对你有一定的参考价值。

深入解析.NET 许可证编译器 (Lc.exe) 的原理与源代码剖析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

许可证编译器 (Lc exe) 的作用是读取包含授权信息的文本文件 并产生一个可作为资源嵌入到公用语言运行库可执行文件中的 licenses 文件  

  在使用第三方类库时 经常会看到它自带的演示程序中 包含有这样的Demo许可文件

复制代码 代码如下: Infragistics Win Misc UltraButton Infragistics Win Misc v Version= Culture=neutral PublicKeyToken=f b b b fdf Infragistics Win Misc UltraLabel Infragistics Win Misc v Version= Culture=neutral PublicKeyToken=f b b b fdf Infragistics Win Printing UltraPrintPreviewDialog Infragistics Win UltraWinPrintPreviewDialog v Version= Culture=neutral PublicKeyToken=f b b b fdf Infragistics Win UltraWinDataSource UltraDataSource Infragistics Win UltraWinDataSource v Version= Culture=neutral PublicKeyToken=f b b b fdf

   这个文件的格式是文本文件 但要按照它的格式要求来写

  控件名称 程序集全名称

  首先根据需要 写一个需要被授权的控件列表 格式如上所示 例如 HostApp exe 的应用程序要引用Samples DLL 中的授权控件 MyCompany Samples LicControl 则可以创建包含以下内容的 HostAppLic txt MyCompany Samples LicControl Samples DLL

  再调用下面的命令创建名为 HostApp exe licenses 的 licenses 文件 lc /target:HostApp exe /plist:hostapplic txt /i:Samples DLL /outdir:c:bindir

  生成将 licenses 文件作为资源嵌入在HostApp exe的资源中 如果生成的是 C# 应用程序 则应使用下面的命令生成应用程序

  csc /res:HostApp exe licenses /out:HostApp exe * cs

   NET Framework SDK目录中的LC EXE文件是由 NET语言编写的 它的功能就是为了根据许可文件的内容 生成资源文件 在编译的最后时刻 由CSC编译器把生成的资源文件嵌入到执行文件中

  用 NET Reflector载入LC EXE 开始源代码分析之旅

   程序的入口处先是分析命令行参数 根据参数的不同来执行指定的功能 先看一个完整的参数列表 代码是下面三行

复制代码 代码如下: if (!ProcessArgs(args))        return num;  

   MSDN有完整的解释 拷贝到下面方便您参考 以减少因查找MSDN引起思路中断 /plist:filename   指定包含授权组件列表的文件名 这些授权组件要包括到 licenses 文件中 每个组件用它的全名引用 并且每行只有一个组件 命令行用户可为项目中的每个窗体指定一个单独的文件 Lc exe 接受多个输入文件并产生一个 licenses 文件 /h[elp]     显示该工具的命令语法和选项 /i:module   指定模块 这些模块包含文件 /plist 中列出的组件 若要指定多个模块 请使用多个 /i 标志 /nologo  取消显示 Microsoft 启动标题 /outdir:path  指定用来放置输出 licenses 文件的目录 /target:targetPE   指定为其生成 licenses 文件的可执行文件 /v   指定详细模式 显示编译进度信息 /?  显示该工具的命令语法和选项 ProcessArgs方法的关键作用是分析出组件列表 程序集列表 如下面的代码所示

复制代码 代码如下:   if ((!flag && (str Length > )) && str Substring( ) ToUpper(CultureInfo InvariantCulture) Equals("TARGET:"))          targetPE = str Substring( );        flag = true;   if ((!flag && (str Length > )) && str Substring( ) ToUpper(CultureInfo InvariantCulture) Equals("PLIST:"))         string str = str Substring( );       if ((str != null) && (str Length > ))                             if (pLists == null)                                             pLists = new ArrayList();                                         pLists Add(str );                     flag = true;        if ((!flag && (str Length > )) && str Substring( ) ToUpper(CultureInfo InvariantCulture) Equals("I:"))          string str = str Substring( );        if (str Length > )                             if (assemblies == null)                                             assemblies = new ArrayList();                                         assemblies Add(str );                 flag = true;

   分 析出组件和程序集之后 再来ResolveEventHandler 委托的含义 如果运行库类加载程序无法解析对程序集 类型或资源的引用 则将引发相应的事件 从而使回调有机会通知运行库引用的程序集 类型或资源位于哪 个程序集中 ResolveEventHandler 负责返回解析类型 程序集或资源的程序集

复制代码 代码如下: ResolveEventHandler handler = new ResolveEventHandler(LicenseCompiler OnAssemblyResolve); AppDomain CurrentDomain AssemblyResolve += handler;

   对第一部参数分析出来的组件列表 依次循环 为它们产生授权许可

复制代码 代码如下: DesigntimeLicenseContext creationContext = new DesigntimeLicenseContext(); foreach (string str in pLists)    key = reader ReadLine();    hashtable[key] = Type GetType(key);        LicenseManager CreateWithContext((Type) hashtable[key] creationContext);

   最后 生成许可文件并保存到磁盘中 等待CSC编译器将它编译成资源文件 嵌入到程序集中

复制代码 代码如下: string path = null; if (outputDir != null)       path = outputDir + @"" + targetPE ToLower(CultureInfo InvariantCulture) + " licenses";   else         path = targetPE ToLower(CultureInfo InvariantCulture) + " licenses";    Stream o = null;  try                  o = File Create(path);            DesigntimeLicenseContextSerializer Serialize(o targetPE ToUpper(CultureInfo InvariantCulture) creationContext);           finally                  if (o != null)                             o Flush();                 o Close();                 

   这种方式是 NET Framework推荐的保护组件的方式 与我们平时所讨论的输入序列号 RSA签名不同 来看一下 商业的组件是如何应用这种技术保护组件的

复制代码 代码如下: using System; using System Web; using System Web UI; using System Web UI WebControls; using System ComponentModel; namespace ComponentArt Licensing Providers   #region RedistributableLicenseProvider     public class RedistributableLicenseProvider : System ComponentModel LicenseProvider         const string strAppKey = "This edition of ComponentArt Web UI is licensed for XYZ application only ";        public override System ComponentModel License GetLicense(LicenseContext context Type type object instance bool allowExceptions)           if (context UsageMode == LicenseUsageMode Designtime)               // We are not going to worry about design time Issue a license         return new ComponentArt Licensing Providers RedistributableLicense(this "The App");             else               string strFoundAppKey;         // During runtime we only want this control to run in the application         // that it was packaged with         HttpContext ctx = HttpContext Current;         strFoundAppKey = (string)ctx Application["ComponentArtWebUI_AppKey"];         if(strAppKey == strFoundAppKey)           return new ComponentArt Licensing Providers RedistributableLicense(this "The App");         else           return null;               #endregion   #region RedistributableLicense Class   public class RedistributableLicense : System ComponentModel License       private ComponentArt Licensing Providers RedistributableLicenseProvider owner;     private string key;     public RedistributableLicense(ComponentArt Licensing Providers RedistributableLicenseProvider owner string key)           this owner = owner;       this key = key;         public override string LicenseKey           get               return key;               public override void Dispose()             #endregion

   首 先要创建一个类型 继承于License类型 再创建一个继承于LicenseProvider的类型 用于颁发许可证 包含在设计时许可和运行时许可 从上面的例子中可以看到 设计时没有限制 可以运行 但是到运行时 你必须有序列号 它才会生成许可对象 而不是返回null给 NET Framework类型 整个验证过程由 NET完成 你只需要像下面这样 应用这个许可保护机制

复制代码 代码如下: [LicenseProvider(typeof(RedistributableLicenseProvider))] public class MyControl : Control     // Insert code here     protected override void Dispose(bool disposing)        /* All ponents must dispose of the licenses they grant         * Insert code here to dispose of the license */     cha138/Article/program/net/201311/14366

相关参考

知识大全 NET程序集反编译器Reflector

NET程序集反编译器Reflector  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &

知识大全 详解.NET中的动态编译

详解.NET中的动态编译  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  代码的动态编译并执行是一

知识大全 详解.NET中的动态编译技术

详解.NET中的动态编译技术  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  代码的动态编译并执行

知识大全 详解.NET中的动态编译[1]

详解.NET中的动态编译[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  代码的动态编译并执

知识大全 详解.NET中的动态编译技术[1]

详解.NET中的动态编译技术[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  代码的动态编译

知识大全 针对不同.NET版本的条件编译

针对不同.NET版本的条件编译  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  为了在NET下能够

知识大全 ASP.NET 2.0的编译模型

ASP.NET2.0的编译模型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  支持两种编译模型(

知识大全 详解.NET中的动态编译[3]

详解.NET中的动态编译[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!usingSystem

知识大全 详解.NET中的动态编译[5]

详解.NET中的动态编译[5]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  对于客户端的输入程

知识大全 详解.NET中的动态编译[2]

详解.NET中的动态编译[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  需要解释的是这里我