分享
 
 
 

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

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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

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.我已经提供了一个可下载的样例解决方案,这个例子是MSDN颜色拾取器组合框控件,这是已被许可的版本。

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有