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

       在商业软件中,为了保证开发者(个人或企业)的利益,防止软件被无限制地复制使用,我们可以为软件加入注册功能,未经注册的软件不允许使用。在进行注册的时候,我们将注册码与安装计算机的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
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值