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

原创 2003年09月19日 00:03:00

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.

office法找到此应用程序的许可证 解

office法找到此应用程序的许可证 一、问题描述 今天打开excel突然出现下面的问题: 有种想卸载office的冲动…… 最后还是找度娘解决了,再次感叹度娘的强大啊! 二、解决方法 下面记...
  • jenyzhang
  • jenyzhang
  • 2016年07月09日 17:10
  • 7846

.net framework 4.5 使用c++编写窗体(WinForm)应用程序

如果是.net framework 2,还有x
  • holdsky
  • holdsky
  • 2014年09月22日 13:24
  • 1905

microsoft office 无法找到此应用程序的许可证……

今天上午可给折腾坏了,弄了一上午没整明白。。听我慢慢道来。 今天打开word,发现不能用了,打开十秒之内必定得关闭,显示的问题如下: 开始不知道怎么回事,因为我什么都没做啊,平白无故出了问题,于是...
  • u011121393
  • u011121393
  • 2014年03月18日 11:29
  • 8163

.NET Framework 各版本介绍和下载链接汇总

一、.NET Framework 版本介绍 自2000年6月22日微软向全球宣布自己的.NET战略,到现在已经十年多了。作为.NET战略的基础,Microsoft .NET Framework ...
  • my98800
  • my98800
  • 2016年03月16日 08:32
  • 2024

安装 VS2012/2013 完成时报错“无法建立到信任根颁发机构的证书链”

问题  在没有接互联网的 Win7/2008 R2 系统上安装 VS2012/2013,安装完成时提示: 安装已完成。 但是,并非所有功能均已正确安装。   下面列出错误都是类似这样: ...
  • bokutake
  • bokutake
  • 2015年11月26日 17:30
  • 10856

.net Framework编写应用程序的过程

---------------------------------------------------------------------------------
  • PianoOrRock
  • PianoOrRock
  • 2017年09月25日 16:07
  • 247

.NET Framework详解之内存机制

.NET Framework详解之内存机制:在.NET Framework中,内存中的资源(即所有二进制信息的集合)分为"托管资源"和"非托管资源".托管资源必须接受.NET Framework的CL...
  • xiaoran1985
  • xiaoran1985
  • 2014年03月11日 11:22
  • 622

.NET Framework各版本汇总以及之间的关系

.NET Framework .NET版本 1.0 1.1 2.0 3.0 3.5 4.0 4.5 完整版本 1.0.3705.0 1.1.4322.573 ...
  • kingmax54212008
  • kingmax54212008
  • 2014年05月15日 13:37
  • 42433

搞懂.NET Framework 历史版本(2017年)

最近被.NET平台各种名词、以及各种版本弄得有些疑惑,开发和部署,对于开发平台版本选择是个基本问题,因此,花了些时间,学习汇总了有关.NET版本演进的历史。 .NET简介 这个平台相信我们都知道...
  • MePlusPlus
  • MePlusPlus
  • 2017年08月02日 22:20
  • 1137

.NET Framework 各个版本之间的关系以及下载地址整理汇总

http://www.cnblogs.com/robnetcn/p/3383481.html .NET Framework 各个版本之间的关系以及下载地址   Version...
  • wlanye
  • wlanye
  • 2015年11月24日 15:56
  • 1419
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.NET Framework给应用程序颁发许可证(下)
举报原因:
原因补充:

(最多只允许输入30个字)