星星之火

燎原之势不可挡
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WinForm应用程序之注册模块的设计与实现

Posted on 2012-11-13 10:21  星星之火116  阅读(5349)  评论(4编辑  收藏  举报

我们在安装一些桌面应用程序的时候,往往在会有提示当前用户使用的是试用版,要进行注册。刚好最近做了一个关于应用程序注册的小demo(这里只是一个思路),在这里和大家分享一下。

项目的要求是这样的:

1. 能获取主机硬盘序列号、网卡MAC地址、CPU编号,并按照一定的算法由此生成机器码

2. 能根据机器码按照一定的算法生成注册码

3. 未注册时,不能使用会员管理功能

好的废话不多说,马上进入正题。还是一步一步通过示例向大家演示是如何实现的。

一、首先新建一个Winform应用程序,分别新建三个Form窗体分别为:Form1(登录),Register(注册)、Form2(主窗体)

界面布局分别如下:

二、首先,获得主机硬盘序列号、网卡MAC地址、CPU编号,并按照一定的算法由此生成机器码,然后再根据机器码生成注册码。(为了方便大家的使用,在这里我已经将其封装为一个类,并导出了类模板点击下载RegisterNumber.zip

该类中有一下的方法

1、GetMac()//获取网卡的MAC地址

2、GetHD()//获取硬盘的序列号

3、GetCPU()//获取CPU编号

4、GetMachineNumber()//根据已经获得的MAC地址、硬盘序列号、CPU编号,组合生成机器码

5、GetRegisterNumber()//根据生成的机器码生成注册码

以上所说的方法在该RegisterNumber类中均有具体的声明实现,有需要的朋友请自己下载使用,这里就不再做具体的讲解了,里边有很清楚的解释。

三、下面先要在Form1也就是登录窗体的Form_Load事件里做如下处理:

private void Form1_Load(object sender, EventArgs e)
        {
            skinEngine1.SkinFile = "WarmColor1.ssk";//为皮肤控件加载文件
            RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE");//打开系统的注册表项,Registry.LocalMachine包含本地计算机的配置数据。该字段读取 Windows 注册表基项 HKEY_LOCAL_MACHINE,OpenSubKey("SOFTWARE")表示打开本地计算机配置数据下SOFTWARE子项
            if (rk.GetValue("ZCM") != null)//获取程序的注册码的值,如果已经注册则有值,此时注册按钮隐藏,未注册时,值为null,此时显示注册按钮
            {
                btnzc.Visible = false;
            }
        }

注册按钮事件处理函数如下:

private void btnzc_Click(object sender, EventArgs e)
        {
            Register r = new Register();//显示注册窗体,进行注册
            r.Show();
        }

登录按钮事件处理函数如下:

private void button1_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;//这里只是一个demo所以只要用户点击登录就可以登录成功,这里只是将DialogResult的值设为OK,并没有直接显示Form2主窗体,因为在登录成功后,Form1登录窗体也就没有用了,所以程序在运行的时候,主线程并非Form1而是From2,因此还需要在Program.cs文件里进行设置。
        }

Program.cs文件里设置如下:

static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 f1 = new Form1();
            if (f1.ShowDialog() == DialogResult.OK)//表示当f1的DialogResult等于Ok时主程序才开始运行,所以在Form1中登录成功时要将Dialogresult设为OK
            {
                Application.Run(new Form2());
            }
        }

四、这时如果要进行注册的话,我们就来看一下注册窗体(Register)里边的代码

1、首先看Register_Load事件里的方法

 private void Register_Load(object sender, EventArgs e)
        {
            txtzcm.Text = RegisterNumber.GetRegisterNumber();//调用RegisterNumber的获取注册码的静态方法,获取当前机器的注册码,并未文本框赋值        
     //FileStream fs = new FileStream(Application.StartupPath + "\\zcm.txt", FileMode.Create, FileAccess.Write);//将注册码写入程序启动项的路径中zcm.txt文件中
            //StreamWriter sw = new StreamWriter(fs, Encoding.Default);
            //sw.Write(txtzcm.Text);
            //sw.Close();
            //fs.Close();
        }

2、然后看注册按钮里的处理事件

 private void button1_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtsr.Text))//先检测用户输入是否为空
            {
                if (txtsr.Text == txtzcm.Text)//再检测用户输入是否和显示的注册码一直
                {
                    RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE",true);
                    rk.SetValue("ZCM", txtsr.Text);//将注册码写入系统的关于程序信息的注册表下SOFTWARE文件下的"ZCM"名中
                    MessageBox.Show("注册成功!请再次登录!");
                }
                else
                {
                    MessageBox.Show("您输入的注册码不正确,请再次输入!");
                }
            }
            else
            {
                MessageBox.Show("请输入注册码!");
            }
        }

五、下面就进入最关键的一部分了,不论用户是否注册,都可以让用户进入程序的主界面,但是如果用户未注册则判断其使用次数是否超过限定的试用次数,如果超过则不能使用,反之则仍可继续试用,并在每次使用时提醒用户剩余试用次数,如果已经注册,则可以获得所有的权限功能。下面看具体的代码实现

private void Form2_Load(object sender, EventArgs e)
        {
            RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE",true);
            if (rk.GetValue("ZCM") != null)//读取系统的注册码,如果已注册则值值不为空可以使用,并标识已注册,反之则未注册
            {
                this.Text = "已注册";
                return;
            }
            this.Text = "试用版(未注册)";
            int count = (int)rk.GetValue("Count", 0);//未注册时获取用户试用的次数,如果是首次使用则赋值为0
            MessageBox.Show("感谢你已经使用了" + count + "次,请先注册再使用!");
            tabc.Visible = false;//因为是使用版,所以有很多 功能无法使用,这里演示将tabControl的visible属性设置为false来演示这种效果
            if (count < 30)//默认试用次数为30次,小于30次时仍可试用,反之则直接结束运行
                {
                    rk.SetValue("Count", count + 1);//需要更新注册表中用来记录登录次数的值,每试用一次,该值就增加一,等大于等于30时,程序试用结束,直接退出
                    count = 30 - count;
                    MessageBox.Show("您试用的是试用版!还有" + count + "次试用机会,请先注册再使用!");    
                }
                else
                {
                    MessageBox.Show("不好意思,请已经超出试用次数!请注册后再使用!");
                    Application.Exit();
                }
        }

好了,到这里程序的注册模块的设计和实现已经完成了,我们已经基本上可以实现了一个简单的程序注册,这里主要用到了Registry类和RegistryKey类用来保存系统的注册码、登录次数,下面我会向大家介绍下这两个类。RegistryKey位于Microsoft.Win32命名空间下。

注册表项是注册表中的基本组织单位,相当于Windows资源管理器中的文件夹。每个具体的注册表项都可以有子项,只要用户具有相应的权限,且注册表项不是基项或基项的下一级项,就可以删除该注册表项。每个注册表项也可带有与其相关联的多个值,它们用于存储信息,通常情况下我们可以创建一个RegistryKey(HKEY_LOCAL_MACHINE\Software)来保存有关计算机上安装的应用程序的信息,就比如我们在本例中就是这样使用来保存用户试用的次数以及机器的注册码。下面是几种常用主键:

HKEY_CLASSES_ROOT该主键包含了文件的扩展名和应用程序的关联信息以及Window Shell和OLE用于储存注册表的信息。该主键下的子键决定了在WINDOWS中如何显示该类文件以及他们的图标,该主键是从HKEY_LCCAL_MACHINE\SOFTWARE\Classes映射过来的。

HKEY_CURRENT_USER该主键包含了如用户窗口信息,桌面设置等当前用户的信息。 

HKEY_LOCAL_MACHINE主键包含了计算机软件和硬件的安装和配置信息,

该信息可供所有用户使用HKEY_USERS该主键记录了当前用户的设置信息,每次用户登入系统时,就会在该主键下生成一个与用户登入名一样的子键,该子键保存了当前用户的桌面设置、背景位图、快捷键,字体等信息。一般应用程序不直接访问改主键,而是通过主键HKEY_CURRENT_USER进行访问。

HKEY_CURRENT_CONFIG该主键保存了计算机当前硬件的配置信息,这些配置可以根据当前所连接的网络类型或硬件驱动软件安装的改变而改变

程序中为了读取指定主键下面的子键和子键中拥有的键值,主要使用了RegistryKey类中的四个方法:OpenSubKey,GetSubKeyNames,GetValueNames,GetValue。具体的用法和意思如下:OpenSubKey ( string name )方法主要是打开指定的子键。GetSubKeyNames ( )方法是获得主键下面的所有子键的名称,它的返回值是一个字符串数组。GetValueNames ( )方法是获得当前子键中的所有的键名称,它的返回值也是一个字符串数组。GetValue ( string name )方法是指定键的键值。

我们在该示例中都有用到这些方法,下面分别为大家演示:

需要声明一下的是为了方便使用,Registry类提供了7个公共的静态域,分别代表7个基本主键分别是:Registry.ClassesRootRegistry.CurrentUserRegistry.LocalMachineRegistry.UsersRegistry.CurrentConfig这里我们以Registry.LocalMachine

来做演示。

RegistryKey rk=Registry.LocalMachine.OpenSubKey("SOFTWARE",true");//这里有两个参数,第一个参数即要打开的文件夹,第二参数为为其指定写的权限
RegistryKey rk1=rk.CreateSubKey("Hello",RegistryKeyPermissionCheck.ReadWriteSubTree);//在SOFTWARE下创建子项,Hello,第二参数为枚举类型即允许对其读写
rk.SetValue("Count",0);//在SOFTWARE下设置键值对,保存登录次数
rk.GetValue("Count",0);//获取Count值,如果当前键值对不存在,则默认为0
rk.DeleteValue("Count");//删除值名称为"Count"的键值对
rk.DeleteSubKey("Hello");//删除SOFTWARE下的子项Hello

有细心的朋友可能会发现上边在Register(注册窗体)的Load事件中还有一些注释的代码如下:

 FileStream fs = new FileStream(Application.StartupPath + "\\zcm.txt", FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs, Encoding.Default);
            sw.Write(txtzcm.Text);
            sw.Close();
            fs.Close();

这段代码的作用是将注册码写入应用程序可执行文件路径下的zcm.txt文件中,这也是一个用来检测用户是否注册的思路,在用户进行注册的时候将注册码写入文本文件中,在登录的时候以打开或者新建的方式从文件中读取注册码,如果已经注册,则可读取到注册码,如果未注册,则显示未注册,并提示用户注册。

      这里只是提供一个思路,希望能给大家带来一些帮助,还请大家多多指点。