C# 利用计算机信息实现软件注册

来源:互联网 发布:游戏特效需要什么软件 编辑:程序博客网 时间:2024/05/16 01:11
       在商业软件中,为了保证开发者(个人或企业)的利益,防止软件被无限制地复制使用,我们可以为软件加入注册功能,未经注册的软件不允许使用。在进行注册的时候,我们将注册码与安装计算机的CPU、硬盘或网卡序列号绑定在一起,这样就可以实现一个注册码对应一台计算机。下面就通过实例来介绍该功能的实现:

       主要功能描述: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

1 0
原创粉丝点击