.NET中的許可證機制
主要類:
System.ComponentModel.License(爲全部許可證提供 abstract 基類。向組件的特定實例授予許可證)
System.ComponentModel.LicenseContext(指定什麼時候可以使用受權的對象,而且提供一種方法,用以獲取爲支持在其域內運行的許可證所須要的附加服務)
System.ComponentModel.LicenseException(表示當組件不能被授予許可證時引起的異常。)
System.ComponentModel.LicenseManager(提供屬性和方法,用以將許可證添加到組件和管理 LicenseProvider)
System.ComponentModel.LicenseProvider(提供 abstract 基類以便實現許可證提供程序)
System.ComponentModel.LicenseProviderAttribute(指定要與類一塊兒使用的 LicenseProvider)
許可證機制簡介
.Net Framework中的許可證驗證機制基於System.ComponentModel命名空間中的License、LicenseContext、LicenseException、LicenseManager、LicenseProvider和LicenseProviderAttribute六個類實現的。
License是一個抽象類,用於表明許可證主體;
LicenseContext中保存了許可證的上下文,其中UsageMode屬性能夠用來獲取當前是運行時(runtime)仍是設計模式(designtime);
LicenseException是許可證相關的異常,當許可證信息不可用時,在調用LicenseProvider(或其派生類)實例的GetLicense方法時將拋出此類型的異常;
LicenseManager是一個密封(sealed)類,LicenseManager提供了多個靜態(static)方法用於驗證許可證、獲取許可證等操做;
LicenseProviderAttribute屬性用於指定某一個類所採用的許可證提供程序(LicenseProvider)的具體類型;
LicenseProvider是一個抽象類,用於表明許可證驗證機制提供程序。LicenseProvider的類型經過LicenseProviderAttribute屬性提供給CLR,當調用LicenseManager的操做時,LicenseManager將根據LicenseProviderAttribute中所提供的LicenseProvider類型建立LicenseProvider實例,並進行相應操做。LicFileLicenseProvider基於文本文件的許可證機制。
簡單應用:
1:首先要建立一個License,可是由於License是抽象的,因此要建立一個集成自License的子類,實現License的一些方法。
2:建立一個LicenseProvider類,這個類要集成LicenseProvider的類。實現一些方法。LicenseProvider類提供了驗證機制的程序。LicenseProvider類要重載GetLicense(LicenseContext,Type ,object ,bool)方法,該方法真正提供了,一些算法,去實現驗證。
3:建立一個自定義的類,而且給該類添加LicenseProviderAttribute屬性。指定對這個類進行驗證的機制採用LiceseProvider。
具體代碼:
定義Licese類
private class MyLicense : License
{
private String mLicenseKey = null;
private MyLicenseProvider mProvider = null;
public MyLicense(MyLicenseProvider provider, String key)
{
this.mProvider = provider;
this.mLicenseKey = key;
}
public override string LicenseKey
{
get { return this.mLicenseKey; }
}
public override void Dispose()
{
this.mProvider = null;
this.mLicenseKey = null;
}
}
定義LicenseProvider類
[ReflectionPermission(SecurityAction.Deny, MemberAccess=false, ReflectionEmit=false)]
internal class MyLicenseProvider : LicenseProvider
{
構造函數
public MyLicenseProvider()
{ }
/// <summary>
/// 獲取本機MAC地址 其實這個無論是獲取本機硬件參數的任何信息均可以這要能標誌該機器便可
/// </summary>
private String GetMacAddress()
{
String macAddr = null;
ManagementClass inetAdapter = new ManagementClass("WIN32_NetworkAdapterConfiguration");
ManagementObjectCollection objList = inetAdapter.GetInstances();
foreach (ManagementObject mobj in objList)
{
if ((bool)mobj["IPEnabled"])
{
macAddr = mobj["MacAddress"].ToString().Replace(":", "-");
break;
}
}
return macAddr;
}
/// <summary>
/// 獲取Assembly所在目錄 獲取應用程序所在的目錄
/// </summary>
private String GetAssemblyPath(LicenseContext context)
{
String fileName = null;
Type type = this.GetType();
ITypeResolutionService service = (ITypeResolutionService)context.GetService(typeof(ITypeResolutionService));
if (service != null)
{
fileName = service.GetPathOfAssembly(type.Assembly.GetName());
}
if (fileName == null)
{
fileName = type.Module.FullyQualifiedName;
}
return Path.GetDirectoryName(fileName);
}
private String Encrypt(String source) 加密算法,能夠用,也可不用,這裏爲了更安全,就用。
{
/**
* 加密算法
*/
byte[] keyData = Encoding.ASCII.GetBytes("");
byte[] ivData = Encoding.ASCII.GetBytes("4iJ9Qw#L");
MemoryStream stream = new MemoryStream();
DES desProvider = new DESCryptoServiceProvider();
CryptoStream cs = new CryptoStream(stream,
desProvider.CreateEncryptor(keyData, ivData),
CryptoStreamMode.Write);
byte[] buffer = Encoding.ASCII.GetBytes(source);
cs.Write(buffer, 0, buffer.Length);
cs.FlushFinalBlock();
cs.Close();
buffer = stream.GetBuffer();
stream.Close();
return Convert.ToBase64String(buffer);
return source;
}
public override License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions)
{
MyLicense license = null;
// 計算MAC地址加密串
String macAddr = this.GetMacAddress();
String encrypt = this.Encrypt(macAddr);
if (context != null)
{
if (context.UsageMode == LicenseUsageMode.Runtime)
{
String savedLicenseKey = context.GetSavedLicenseKey(type, null);
if (encrypt.Equals(savedLicenseKey))
{
return new MyLicense(this, encrypt);
}
}
if (license != null)
{
return license;
}
// 打開License文件 'license.dat'
String path = this.GetAssemblyPath(context);
String licFile = Path.Combine(path, "license.dat");
if (File.Exists(licFile))
{
Stream fs = new FileStream(licFile, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
String readedLicenseKey = sr.ReadToEnd();
sr.Close();
fs.Close();
if (encrypt.Equals(readedLicenseKey))
{
license = new MyLicense(this, encrypt);
}
}
if (license != null)
{
context.SetSavedLicenseKey(type, encrypt);
}
}
if (license == null)
{
System.Windows.Forms.MessageBox.Show("!!!還沒有註冊!!!");
return new MyLicense(this, "evaluate");
}
return license;
}
指定該類進行許可驗證的程序採用MyLicenseProvider 這句必須的。
[LicenseProvider(typeof(MyLicenseProvider))]
public partial class LicenseHelper
{
private License mLicense = null;
public LicenseHelper()
{
this.mLicense = LicenseManager.Validate(typeof( LicenseHelper), this);
}
~ LicenseHelper() 析構函數,在C#中,不經常使用。
{
if (this.mLicense != null)
{
this.mLicense.Dispose();
this.mLicense = null;
}
}
}
這樣。在程序中調用LicenseHelper是就要進行驗證,不然。就會出現異常。
該方法也能夠對軟件進行加密,只是在GetLicense(LicenseContext, type, object,bool);方法中寫的機密算法要複雜一些。可是道理都是這樣的。算法
出處:http://blog.csdn.net/joyhen/article/details/22715223設計模式