.NET Framework给应用程序颁发许可证(上)

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>


 .NET Framework给应程序颁发许可证


NET_Framework/LicensedApps.html">http://www.codeguru.com/NET_Framework/LicensedApps.html

by Kenn Scribner
翻译:邹建强

译者注:或许有些术语与你所见到不一致,那么请给我指出来;如果有些语句错误也请帮我指出来,谢谢

  如果你正在阅读本文,毫无疑问你是一个Windows平台软件的开发人员。如果你是一个Windows软件的开发人员的话,你写软件或许是因为你对写软件充满了激情。我乐于整日地编写代码,因为觉得这是种享受。我相信你在很多方面与我感觉相同。这或许是生活的好方式。

  可是这是可遇而不可求的事。如果你不考虑写软件的经济因素,我们会遇到一个简单平实的道理:当我们因为喜欢而努力工作时,我们要养家糊口,要付该死的帐单,坦率而言,我们还想全家偶尔去外出渡假。毕竟使用我们软件的很多人可能对他们职业的态度与我们相同,但是日常生活中人们对此的看法却很不公平。他们工作并想为他们的勤奋工作得到报酬,甚至他内心里热爱他们正在做的和从事的事情。

  问题是当最终用户得到软件时,软件经常成了一件说不清楚的事情。他们所看到的全部东西只是应用程序自身,甚至,这个程序只会在有电时存在电脑内存短暂的一会儿。似乎很难看出这是花了成百上千个小时开发测试出来的产品,或者至少无法和汽车、电冰箱这样的物理直观的东西比较。正直、勤奋的电脑用户从不会想到要偷窃一辆汽车或是一台电冰箱,但是他们会经常与朋友交换软件,他们甚至知道这是有违软件的授权协议的。但是软件仅仅是CD上的数码而已,对吧,把软件传给朋友或兄弟它能有什么损伤吗?

  不错,你知道这个答案是什么——用户没有对你的努力工作付钱。按商业术语的说法你没有了收入。如果你没有足够的收入,作为商家,你无法维持你的生意。作为个人,你可能不能承担你的财务支出(你付费的帐单)。因此你或是找一个速食连锁店工作,或是宣布破产并且去住在某个高速路桥下面的纸板房(cardbox)里。就本我而言,我宁愿相信用户会为软件付费,会对我设计、开发、测试、市场宣传、分发软件所作出的努力付费的。

  解决方案就是软件授权许可证。作为一个工业,许多人设法以各种方式解决这个问题。在过去,软件是存在一种防复制的媒介(记得是在一种有多余磁轨的软盘上。译者注:也有在磁盘上人为制造一个坏区的)上销售的。现在通常的做法是要求你键入一串密钥才能使软件包正常使用。微软最近开始对他们高端的操作系统和产品(诸如Office,可能是最经常盗版的软件)进行基于互联网的在线软件授权。在.NET Framework里,也存在这样的技术宝藏,你能用它来颁发你的软件的授权许可证,这正是我现在就要展示给你的。

控件许可证

  几乎你阅读的有关.NET 许可证的每样东西都是把两种许可证概念绑定在一起的。一种控件的许可证概念,另一种思想是控件开发者所装配的控件许可证可以在设计时进行或是在运行时进行。当许可发生时,你可以把框架许可(Framework licensing)应用到派生自System.Windows.Forms.Control的任何类,它包含了整个Windows Forms的应用程序,但是我会以控件自身开始。图1所示为许可证UML静态类的基本控件图表。


图1. 许可证静态类.NET控件图表

  在图2所显示(一个UML顺序图表)的是一个通常的的执行顺序。在被许可证控件的构造函数中要求一个来自许可证管理者(LicenseManager)的授权许可证:

license = LicenseManager.Validate(typeof(MyLicensedControl), this);

  在这种情况下,构造函数用于控件许可,在MyLicensedControl这个类中实现。极趣的是,在处理许可证对象自身上你可能什么也不需要做(取决于你许可证的实现),除了适当安排附加加资源外。从这个暗箱里,我们采取的重要步骤就是调用,许可证管理器申请一个许可证。如果因某些原因许可证没有被接收认可,Validate() 调用会抛出一个失败异常,如果异常想被得到。反之,如果异常被抑制,则返回一个空许可证。 (LicenseProvider.GetLicense() 控件调用,以及默认的Framework实现都允许异常。)


图2.控件许可顺序

  许可证管理者依次调用控件许可证提供者的GetLicense()方法。许可证管理者,一个.NET Framework组件,是如何知道所用的许可证提供者是哪一个的呢?毕竟你提供了许可证提供者... 答案是通过传统.NET方式中的元数据、通过属性:

[LicenseProvider(typeof(MyLicenseProvider))]
public class MyLicensedControl : System.Windows.Forms.Control
{
   ...
}

  许可证管理者会寻找附加许可证控件类的LicenseProvider属性。由于LicenseProvider属性把许可证提供者的类型当做构造函数的输入,许可证管理器在要求校验这个许可证时,能够射这个信息。你的许可证提供者必须派生自类LicenseProvider,必须重载GetLicense(),这是一个方法(MustOverride 对于VB用户而言):

public class MyLicenseProvider : 
                System.ComponentModel.LicenseProvider
{
   ...

   
   
   
   
   public override License GetLicense(
      LicenseContext context,  
      Type type,  
      object instance,  
      bool allowExceptions)  
   {
      ...
   }
}

  在.NET环境中,允许授权认可的魔法构成了我刚刚描述的程序。但最终,真正的许可证魔法是在GetLincense()方法中编码的。 

  我们在有太多想象前,你应该了解,微软用框架装配一个被称之为LicFileLicenseProvider的基本的许可证提供者。我会完整地对你描述如何使用LicFileLicenseProvider,我也相信任何发送他们软件许可证的人,很可能会避免这样简单的方案,以利于他们自己。更有建设性的方案,我会在描述完LicFileLicenseProvider之后介绍它们其中一个。

LicFileLicenseProvider

  LicFileLicenseProvider的前提简单,它会检查许可证文件的存在性。如果文件存在就会检查文件内容是否合法。这个文件可能和程序一起保存在磁盘上,或者可能被编码成一个应用程序资源文件,你需要另写一些代码把它读取出来。如文件存在并且内容合法,许可证提供者会颁发一个许可证给许可证管理者,最终颁发给这个控件。否则,许可证提供者会抛出一个LicenseException 异常,并且你的控件进程将会阻塞并且死亡。

  LicFileLicenseProvider重载GetLicense()方法,这是必须的,同时又提供了两个额外的虚拟方法,IsKeyValid()GetKey()。使用LicFileLicenseProvider,它在框架中实现时,GetKey()会在程序集的执行目录当中寻找一个文件,文件命名格式是{full name}.lic,这里{full name}是许可证控件类的完整类型名,比较代表性的格式是{assembly name}.{class name}。如果程序集 MyControlAssembly声明了我们已经使用的许过控件,在这个文件中许可证文件会被命名成:

MyControlAssembly.MyLicensedControl.lic

  IsKeyValid()方法用所掌握的该文件内容与字串"{licensed class} is a licensed component." (包括句点)比较。我举的例子中,文件MyControlAssembly.MyLicensedControl.lic容纳了这个字串"MyControlAssembly.MyLicensedControl is a licensed component.",如果这个许可证文件丢失了,或是内容不正确,合法性校验会失败,并且这个控件不会被实例化。I've included with downloadable samples solution an example that has a licensed version of the MSDN sample color-picker ComboBox control.我已经提供了一个NET_Framework/LicensedApps.zip">可下载的样例解决方案,这个例子是MSDN颜色拾取器组合框控件,这是已被许可的版本。

  由于IsKeyValid()GetKey()是虚拟方法,因此你很容易派生一个新类。这个新类或为许可证文件呈现在别的地方,或对一个不同的字串进行校验(或许是一个被加密的字串、或是一个简单地使用不同短语的字串)。无论怎样,由于基类已经声明了这样的功能,一个“良好”的方法实现仍旧会基本上处理这些许可证文件。如果你宁愿用一个完全不同的方式来实现许可证方案的话,直接从LicenseProvider派生一个许可证提供者是一个很好的选择。由于我对大家的智商很有信心,因此我不打算提供提供一个被派生的许可证文件提供者的示例。相反,我会描述一些可选的许可证方案。

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值