主要功能描述:1.没有注册过的软件,不允许使用,打开后,直接进入注册界面,完成注册后才可以正常使用。2.注册界面实现用户计算机机器码的提取。3.开发者根据用户提供的机器码,利用注册码生成器生成注册码。4.用户可使用开发者提供的注册码进行软件注册。
公共类
注册类
该类主要实现软件注册需要的各类方法,包括获取CPU、硬盘ID号,加密、计算注册码,写注册表等操作。源代码中已经做过了详细注释,这里就不在过多介绍。需要注意的是,为了使用ManagementClass类,需要添加System.Management引用。注册类源代码如下:
static class RegisterClass
{
public static bool Stupids = true;//输入注册码与实际注册码相同时返回
public static bool Cat = false;//与实际注册码不同时返回
public static int[] intCode = new int[127];//用于存密钥
public static int[] intNumber = new int[25];//用于存机器码的,Ascii值
public static char[] Charcode = new char[25];//存储机器码字
/// <summary>
/// //步骤一: 获得CUP序列号和硬盘序列号的实现代码如下:获得CPU的序列号
/// </summary>
/// <returns></returns>
public static string getCpu()
{
string strCpu = null;
ManagementClass myCpu = new ManagementClass("win32_Processor"); //win32_Processor为WMI类路径
ManagementObjectCollection myCpuConnection = myCpu.GetInstances();
foreach( ManagementObject myObject in myCpuConnection)
{
strCpu = myObject.Properties["Processorid"].Value.ToString();//获取cpu的id号
break;
}
return strCpu;//以字符串形式返回cpu序列号
}
/// <summary>
/// //取得设备硬盘的卷标号
/// </summary>
/// <returns></returns>
public static string GetDiskVolumeSerialNumber()
{
ManagementClass mc =
new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObject disk =
new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");//初始化c盘序列号的WMI实例
disk.Get();//将WMI类信息绑定到实例对象
return disk.GetPropertyValue("VolumeSerialNumber").ToString();//以字符串形式返回硬盘卷编号
}
/// <summary>
/// 步骤二: 收集硬件信息生成机器码
/// </summary>
/// <returns></returns>
public static string CreateCode(out string machinecode)
{
string temp = getCpu() + GetDiskVolumeSerialNumber();//获得24位Cpu和硬盘序列号
string[] strid = new string[24];//
for (int i = 0; i < 24; i++)//把字符赋给数组
{
strid[i] = temp.Substring(i, 1);
}
temp = "";//将temp置空
//Random rdid = new Random();
for (int i = 0; i < 24; i++)//从数组随机抽取24个字符组成新的字符生成机器三
{
//temp += strid[rdid.Next(0, 24)];//使用随机数,这里相当于对24位序列号进行了重新排序
temp += strid[i+3>=24?0:i+3];//这里使用的是固定算法
}
machinecode = temp;//本机序列号,即机器码
return GetMd5(temp);//对重新排序后的序列号,进行MD5加密(temp可以作为发送回来的值)
}
/// <summary>
///步骤三: 使用机器码,生成密钥, 代码如下:
/// </summary>
public static void setIntCode()//给数组赋值个小于10的随机数
{
Random ra = new Random();
for (int i = 1; i < intCode.Length; i++)
{
intCode[i] = ra.Next(0, 9);//随机生成127个0-9的数字,组成一个数组,作为密钥
}
for (int i = 1; i < intCode.Length; i++)
{
intCode[i] = i + 3 > 9 ? 0 : i + 3;//使用固定算法,有利于是否注册的验证
}
}
/// <summary>
/// 根据cpu和硬盘卷,生成注册码
/// </summary>
/// <param name="code">createcode 的返回值</param>
/// <returns></returns>
public static string GetCode(string code)
{
if (code != "")
{
//把机器码存入数组中
setIntCode();//利用随机数,初始化127位数组
for (int i = 1; i < Charcode.Length; i++)
{
Charcode[i] = Convert.ToChar(code.Substring(i - 1, 1));//把机器码存入数组中
}
for (int j = 1; j < intNumber.Length; j++)
{
intNumber[j] =
intCode[Convert.ToInt32(Charcode[j])] + //做密钥的下标
Convert.ToInt32(Charcode[j]); //把(机器码)字符的ASCII值存入一个整数组中。这里也是一种加密方式
}
string strAsciiName = null;//用于存储注册码
for (int j = 1; j < intNumber.Length; j++)
{
//MessageBox.Show((Convert.ToChar(intNumber[j])).ToString());
//判断字符ASCII值是否0-9之间
if (intNumber[j] >= 48 && intNumber[j] <= 57)
{
strAsciiName += Convert.ToChar(intNumber[j]).ToString();
}
//判断字符ASCII值是否A-Z之间
else if (intNumber[j] >= 65 && intNumber[j] <= 90)
{
strAsciiName += Convert.ToChar(intNumber[j]).ToString();
}
//判断字符ASCII值是否a-z之间
else if (intNumber[j] >= 97 && intNumber[j] <= 122)
{
strAsciiName += Convert.ToChar(intNumber[j]).ToString();
}
else//判断字符ASCII值不在以上范围内
{
if (intNumber[j] > 122)//判断字符ASCII值是否大于z
{
strAsciiName += Convert.ToChar(intNumber[j] - 10).ToString();
}
else
{
strAsciiName += Convert.ToChar(intNumber[j] - 9).ToString();
}
}
}
return strAsciiName;//返回注册码,字符串形式
}
else
{
return "";
}
}
/// <summary>
/// 步骤四:进行注册,并将注册信息写入到注册表
/// </summary>
/// <param name="currentCode">现在输入的注册码</param>
/// <param name="realCode">程序内部生成的注册码</param>
/// <returns></returns>
public static bool RegistIt(string currentCode, string realCode)
{
if (realCode != "")
{
if (currentCode.TrimEnd().Equals(realCode.TrimEnd()))
{
Microsoft.Win32.RegistryKey retkey =
Microsoft.Win32.Registry.CurrentUser.//当前用户首选项信息
OpenSubKey("software", true).CreateSubKey("SLDataConvert").
CreateSubKey("SLDataConvert.ini");
retkey.SetValue("SLDataConvert", realCode);//设值,将注册码写入到注册表中
retkey = Microsoft.Win32.Registry.LocalMachine.//本地计算机配置信息
OpenSubKey("software", true).CreateSubKey("SLDataConvert").
CreateSubKey("SLDataConvert.ini");
retkey.SetValue("SLDataConvert", realCode);//设值,将注册码写入到注册表中;realcode为注册码
return Stupids;//如果输入的注册码与实际的相同,则返回true,否则
}
else
{
return Cat;//否则返回false
}
}
else { return Cat; }
}
/// <summary>
/// 检查是否已经注册
/// </summary>
/// <param name="sn">本机序列号</param>
/// <param name="registercode">注册码</param>
/// <returns></returns>
public static bool BoolRegist(string sn,string registercode)
{
string[] keynames;
bool flag = false;
Microsoft.Win32.RegistryKey localRegKey = Microsoft.Win32.Registry.LocalMachine;
Microsoft.Win32.RegistryKey userRegKey = Microsoft.Win32.Registry.CurrentUser;
try
{
keynames = localRegKey.OpenSubKey("software\\SLDataConvert\\SLDataConvert.ini\\" /*+ GetMd5(sn)*/).GetValueNames();
foreach (string name in keynames)
{
if (name == "SLDataConvert")
{
if (localRegKey.OpenSubKey("software\\SLDataConvert\\SLDataConvert.ini\\" /*+ GetMd5(sn)*/).GetValue("SLDataConvert").ToString() == registercode)
{
flag = true;
}
}
}
keynames = userRegKey.OpenSubKey("software\\SLDataConvert\\SLDataConvert.ini\\" /*+ GetMd5(sn)*/).GetValueNames();
foreach (string name in keynames)
{
if (name == "SLDataConvert")
{
if (flag && userRegKey.OpenSubKey("software\\SLDataConvert\\SLDataConvert.ini\\" /*+ GetMd5(sn)*/).GetValue("SLDataConvert").ToString() == registercode)
{
return true;//两项都为true才判定为已经注册
}
}
}
return false;
}
catch(Exception ex)
{
SysCommInfo.WriteLogFiles(ex.ToString());//写错误日志文件
return false;
}
finally
{
localRegKey.Close();
userRegKey.Close();
}
}
/// <summary>
/// 利用MD5哈希算法进行加密
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static string GetMd5(object text)
{
string path = text.ToString();
MD5CryptoServiceProvider MD5Pro = new MD5CryptoServiceProvider();
Byte[] buffer = Encoding.GetEncoding("utf-8").GetBytes(text.ToString());//将对象转化为字节数组
Byte[] byteResult = MD5Pro.ComputeHash(buffer);//计算指定字节数组的哈希值
string md5result = BitConverter.ToString(byteResult).Replace("-", "");//将字节数组转化为字符串
return md5result;//返回加密后的字符串
}
}
公共类
在这里,公共类的主要功能是对捕捉的系统异常进行错误日志的记录。在此公共类中,大家还可以根据需要添加自己的方法变量,以方便对整个开发项目的管理操作。
源码如下:
static class SysCommInfo
{
public static void WriteLogFiles(string loginfo)
{
string filepath = Application.StartupPath + "\\LogFiles\\";
if (!System.IO.Directory.Exists(filepath))
{
System.IO.Directory.CreateDirectory(filepath);
}
string filename = DateTime.Now.ToString("yyyyMMdd") + ".log";
if (!System.IO.File.Exists(filepath + filename))
{
System.IO.File.Create(filepath+filename);
}
string recordtime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ": ";
StreamWriter sw = new StreamWriter(filepath + filename, true, Encoding.Unicode);
sw.WriteLine(recordtime + loginfo);
sw.Flush();
sw.Close();
}
软件注册
没有注册过的软件,打开后会进入如下图所示的注册界面。
图1
用户点击【生成机器码】,软件自动提取机器码并显示到软件界面上。用户将该机器码提供给开发者,开发者利用此机器码来生成该计算机的注册码。提供源码如下:
public partial class RegisterForm : Form
{
private static string machinecode = "";//机器码序列号
private static string Md5Code = "";//加密后序列号
private static string registercode = "";//注册码
public RegisterForm()
{
InitializeComponent();
}
private void RegisterForm_Load(object sender, EventArgs e)
{
tb_RegisterCode.Enabled = false;
btn_Activation.Enabled = false;
tssl_timer.Text = "当前时间:" + System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
this.reg_timer.Interval = 1000;
this.reg_timer.Start();
//首先检测这台计算机有没有注册
Md5Code = RegisterClass.CreateCode(out machinecode);
registercode = RegisterClass.GetCode(Md5Code);//重新计算得到注册码
if (RegisterClass.BoolRegist(machinecode, registercode))
{
//已经注册的话,进入软件主界面,否则进入注册界面
btn_Activation.Enabled = true;
btn_Register.Enabled = false;
}
else
{
btn_Activation.Enabled = false;
btn_Register.Enabled = true;
}
}
private void btn_Register_Click(object sender, EventArgs e)
{
//在界面上显示机器码,进行MD5加密前的
string manchiecode = "";
string Md5code = RegisterClass.CreateCode(out manchiecode);
tb_MachineCode.Text = Md5code;//进行Md5加密后的机器码
if (tb_MachineCode.TextLength == 32 && Md5code != "")
{
tssl_info.Text = "生成机器码成功!";
}
}
private void btn_Activation_Click(object sender, EventArgs e)
{
try
{
//输入注册码,点击激活,检验输入的验证码是否与实际的相同
if (tb_RegisterCode.Text.Trim() != "")
{
bool flag = false;
flag = RegisterClass.RegistIt(tb_RegisterCode.Text.Trim(), registercode);//进行注册
if (flag)
{
tssl_info.Text = "注册成功!";
MessageBox.Show("注册成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Hide();
string startup = Application.StartupPath;
System.Diagnostics.Process.Start(startup + "\\SLDataConvertor");//完成注册之后,重启打开软件
this.Close();
this.Dispose();
}
}
else
{
MessageBox.Show("请输入注册码", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
SysCommInfo.WriteLogFiles(ex.ToString());
}
}
private void tb_MachineCode_TextChanged(object sender, EventArgs e)
{
if(tb_MachineCode.TextLength==32)
{
tb_RegisterCode.Enabled = true;
}
else
{
tb_RegisterCode.Enabled = false;
}
}
private void tb_RegisterCode_TextChanged(object sender, EventArgs e)
{
if (tb_RegisterCode.TextLength == 24)
{
btn_Activation.Enabled = true;
}
else
{
btn_Activation.Enabled = false;
}
}
private void reg_timer_Tick(object sender, EventArgs e)
{
tssl_timer.Text = "当前时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
}
注册码生成器
将用户提供的机器码输入到下图机器码的文本框中,然后点击生成注册码。生成的注册码会显示到界面上的注册码文本框。用户,利用生成的注册码完成软件的注册。
图2
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
btn_CodeGenerate.Enabled = false;
}
private void btn_CodeGenerate_Click(object sender, EventArgs e)
{
try
{
if (tb_MachineCode.Text != "")
{
string m_registration = RegisterClass.GetCode(tb_MachineCode.Text.Trim());
tb_RegisterCode.Text = m_registration;
}
else
{
MessageBox.Show("请先输入机器码","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
SysCommInfo.WriteLogFiles(ex.ToString());
}
}
private void btn_exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void tb_MachineCode_TextChanged(object sender, EventArgs e)
{
if (tb_MachineCode.TextLength == 32)
{
btn_CodeGenerate.Enabled = true;
}
else
{
btn_CodeGenerate.Enabled = false;
}
}
}
参考文献:http://www.cnblogs.com/StupidsCat/archive/2012/05/29/2524143.html