分享
 
 
 

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

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

by Kenn Scribner

翻译:邹建强

注册表许可证提供者

正如我前面所提到的,大多数许可证的校验工作是由你的许可证提供者的 GetLicense() 方法去做的。这里有些代码,是为我自己的注册表许可证提供者写的(你可以在RegistryLicenseProvider.cs 这个源文件示例中找到):

public override License GetLicense(

LicenseContext context,

Type type,

object instance,

bool allowExceptions)

{

// We'll test for the usage mode...run time v. design time.

// Note we only check if run time...

if (context.UsageMode == LicenseUsageMode.Runtime)

{

// The Registry key we'll check

RegistryKey licenseKey =

Registry.CurrentUser.OpenSubKey("Software\\Acme\\HostKeys");

if ( licenseKey != null )

{

// Passed the first test, which is the existence of the

// Registry key itself. Now obtain the stored value

// associated with our app's GUID.

string strLic =

(string)licenseKey.GetValue(type.GUID.ToString()); // reflected!

if ( strLic != null )

{

// Passed the second test, which is some value

// exists that's associated with our app's GUID.

if ( String.Compare("Installed",strLic,false) == 0 )

{

// Got it...valid license...

return new RuntimeRegistryLicense(type);

} // if

} // if

} // if

// if we got this far, we failed the license test. We then

// check to see if exceptions are allowed, and if so, throw

// a new license exception...

if ( allowExceptions == true )

{

throw new LicenseException(type,

instance,

"Your license is invalid");

} // if

// Exceptions are not desired, so we'll simply return null.

return null;

} // if

else

{

return new DesigntimeRegistryLicense(type);

} // else

}

下面这部分检查代码比较令人感兴趣,我们可以检查当前运行在什么模式下,是设计时还是运行时:

if (context.UsageMode == LicenseUsageMode.Runtime)

{

... // Run time mode

}

else

{

... // Design time mode

} // else

如果在设计时操作,我们会简单地创建并返回一个我们设计时许可证对象的实例:

return new DesigntimeRegistryLicense(type);

然而如果是运行时,我们可以打开我们特殊的注册键值去寻找我们应用程序的GUID键值对。我们如下方式打开注册表键:

RegistryKey licenseKey =

Registry.CurrentUser.OpenSubKey("Software\\Acme\\HostKeys");

通过反射应用程序GUID,我们生成这个键值。这个GUID来自于我们得到的对象(还记得放在我们许可证类型的GuidAttribute属性吧):

string strLic =

(string)licenseKey.GetValue(type.GUID.ToString());

GetValue() 方法不是返回与这个键相关联的值就是返回null,因此我们对null值测试,对我们期望返回的值进行检查看是不是代表一个合法的许可证:

if ( strLic != null )

{

// Passed the second test, which is some value

// exists that's associated with our app's GUID.

if ( String.Compare("Installed",strLic,false) == 0 )

{

// Got it...valid license...

return new RuntimeRegistryLicense(type);

} // if

} // if

如果一切正常,我们会返回我们运行时许可证对象的一个新实例。否则我们会检查是否允许异常,如果是就抛出一个新许可证异常:

if ( allowExceptions == true )

{

throw new LicenseException(type,

instance,

"Your license is invalid");

} // if

如异常不被允许,我们就简单的返回null。

这种情形下许可证类是一样的,但是相同不是必需的。运行时许可证如下显示:

public class RuntimeRegistryLicense : License

{

private Type type;

public RuntimeRegistryLicense(Type type)

{

if ( type == null )

throw new NullReferenceException(

"The licensed type reference may not be null.");

this.type = type;

}

public override string LicenseKey

{

get

{

// Simply return the application's GUID

return type.GUID.ToString();

}

}

public override void Dispose()

{

}

}

由于从基类License派生了一个新的许可证类型,我必须重载这个 LicenseKey 属性(它是abstract方法)。当被要求时,会返回应用程序的GUID。不管怎样,我可以重新得到注册表值或者对定期的失效和别的某些非法条件做检查。

更多的其它许可证方案

我在这里演示的技巧相当基础。但是一方面许多用户在没有大量帮助的情况下不能打开注册表找到键值,另一方面有些人有相当的能力去破解这个方案。因此,你要做的就是要让你的许可证方案更难破解。

你所要做的最明显的事就是用一个产品有效期数据来替换我的简单的“Installed”字串(并且对这个值加密)。或者你写一个更复杂的许可证提供者,让它调用Windows或Web服务向它们申请一个执行应用程序的许可。这两种方式我都写过非常有效。正如我提过的,许可证对象自身可以使自己无效,迫使应用程序关闭,它得到的只是些无效的证书。或许可以从Web服务或数据库中检查的许可证来决定这个应用程序日常的许可证状态。无论在何种情况下,你要确保把你产品汇编后结果做混淆处理!

结论

如果你已经阅读到了这里并且研究了基本的框加许可过程,你可能奇怪:为什么我写了这么多东西都是局限于这个框架(.NET Framework)内的呢?我们难首不能创建一个自己的许可证管理器吗?为什么没有一个非框架的许可证构架呢?只要把一个布尔值传线GetLicense() 方法启用异常呢?(我个人希望是指定给LicenseManger或许可证类一个属性而不是把一个布尔值传给 GetLicense()…… 我还没看见过有任何别的方式能改变默认框架行为)

我仅能假设使用框架的许可证架构而不是你自己的这会对你的将来开发更有利。毕竟你要遵循框架规定的模式,改变框架可能会对你造成一定的影响。因为你肯定要利用一些框架提供的组件,重用这些资源可以节省(尽管少)你维护的开销。

就许可证自身而言,唯一的限制是你自己的想象力。现在就去赚回你损失的钱吧!

源代码下载

源代码下载: LicensedApps.zip - 76 kb

About the Author...

Kenn Scribner finds himself consulting and helping other developers understand the complexities of Windows and COM programming. Kenn considers himself fortunate to pursue his hobby as a career and enjoys sharing his experiences with other developers. To that end, Kenn has written four books: MFC Programming with Visual C++ 6 Unleashed, Teach Yourself ATL in 21 Days, Understanding SOAP, and his newest, Applied SOAP: Implementing .NET Web Services. He has contributed to several other books, including Mike Blasczak's Professional MFC with Visual C++ 6. Kenn has also contributed numerous XML and SOAP articles to Visual C++ Developer, which you can find (along with many products and code samples) at his personal Web site, EnduraSoft.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有