Posted on 2012-11-13 10:21 星星之火116 阅读(3260) 评论(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);
           <span style=""> Form1 f1 = new Form1();
            if (f1.ShowDialog() == DialogResult.OK)//表示当f1的DialogResult等于Ok时主程序才开始运行,所以在Form1中登录成功时要将Dialogresult设为OK
            {
                Application.Run(new Form2());
            }
</span>        }

四、这时如果要进行注册的话,我们就来看一下注册窗体(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.ClassesRoot,Registry.CurrentUser,Registry.LocalMachine,Registry.Users,Registry.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文件中,这也是一个用来检测用户是否注册的思路,在用户进行注册的时候将注册码写入文本文件中,在登录的时候以打开或者新建的方式从文件中读取注册码,如果已经注册,则可读取到注册码,如果未注册,则显示未注册,并提示用户注册。

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

WinForm应用程序之注册模块的设计与实现的更多相关文章

  1. winform 发布应用程序 提示 “未能注册模块(程序路径)\ieframe.dll”

    程序安装的时候出现未能注册模块(程序路径)\ieframe.dll提示 这种情况的出现,是因为引用的shdocvw.dll,目前发现了一个折中的解决方法,在安装程序里面,可以看到ieframe.dll ...

  2. 在WinForm应用程序中快速实现多语言的处理(2)--开发框架模块的整合

    我在上篇随笔<在WinForm应用程序中快速实现多语言的处理>里面介绍了Winform开发中多语言的处理解决方案,整个多语言解决方案是以实际需求为驱动,以减少代码改动,高效处理为目的,通过 ...

  3. C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式

    C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式 C#实现自动启动的方法-两种方法 源码下载地址: ...

  4. visual studio 设计第一个WinForm小程序

    WinForm小程序之消息框 首先打开visual studio 软件,然后[文件]-[新建]-[项目]-[Visual C#]-[Windows],选择Windows窗体应用程序,根据自己的需要修改 ...

  5. 在WinForm应用程序中快速实现多语言的处理

    在国际化环境下,越来越多的程序需要做多语言版本,以适应各种业务需求的变化.在Winform应用程序中实现多语言也有常规的处理方式处理,不过需要针对每个语言版本,重新修改Winform界面的显示,对一些 ...

  6. iOS开发一个用户登录注册模块需要解决的坑

    最近和另外一位同事负责公司登录和用户中心模块的开发工作,开发周期计划两周,减去和产品和接口的协调时间,再减去由于原型图和接口的问题,导致强迫症纠结症状高发,情绪不稳定耗费的时间,能在两周基本完成也算是 ...

  7. PHP+jQuery 注册模块开发

    /* ******* 环境: Apache2.2.8 + PHP5.2.6 + MySQL5.0.51b + jQuery-1.8.3.min.js ************** 其他组件:Zend_ ...

  8. Java入门:用户登录与注册模块1(实践项目)——分析

    任务描述:用户登录与注册是大多数软件都拥有的一个模块.请编写一个控制台程序,实现用户的登录与注册功能,并且用户能够修改自己信息. [需求分析]由于本程序是一个演示程序,用户的信息我们做简化处理,仅包括 ...

  9. Java SSH框架系列:用户登录模块的设计与实现思路

    1.简介用户登录模块,指的是根据用户输入的用户名和密码,对用户的身份进行验证等.如果用户没有登录,用户就无法访问其他的一些jsp页面,甚至是action都不能访问.二.简单设计及实现本程序是基于Jav ...

随机推荐

  1. mysql 用sql语句查询一个表中的所有字段类型、注释

    SELECT column_name,column_comment,data_type FROM information_schema.columns WHERE table_name='表名' AN ...

  2. java简单的页面制作

    package 界面; import java.awt.*; import javax.swing.JFrame; import javax.swing.*; //import javax.swing ...

  3. winform继承窗体,无法修改父窗体控件问题处理笔记

    问题描述: 一个窗体集成父窗体,发现无法直接修改父窗体的控件,比如修改大小等,父窗体控件已经设置为public,如果做成一个dll被引用无此问题 特征: 不禁使父窗体控件,就算新加一个控件也会这样:鼠 ...

  4. LSMW应用

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. hdu 1075 (map)

    http://acm.hdu.edu.cn/showproblem.php?pid=1075 What Are You Talking About Time Limit: 10000/5000 MS ...

  6. FZU 2213 Common Tangents(公切线)

    Description 题目描述 Two different circles can have at most four common tangents. The picture below is a ...

  7. Entity Framework 学习初级篇--基本操作:增加、更新、删除、事务(转)

    摘自:http://www.cnblogs.com/xray2005/archive/2009/05/17/1458568.html 本节,直接写通过代码来学习.这些基本操作都比较简单,与这些基本操作 ...

  8. 详解.NET异步

    在说到异步前,先来理一下几个容易混淆的概念,并行.多线程.异步. 并行,一般指并行计算,是说同一时刻有多条指令同时被执行,这些指令可能执行于同一CPU的多核上,或者多个CPU上,或者多个物理主机甚至多 ...

  9. iOS - Swift NSUserDefaults 数据存储

    前言 public class NSUserDefaults : NSObject 用来保存应用程序设置和属性.用户保存的数据.用户再次打开程序或开机后这些数据仍然存在.如果往 userDefault ...

  10. bootstrap学习笔记<二>(标题,段落样式)

    标题.样式:class="h1"~class="h6" bootstrap中重新定义了h1~h6标签,具体差别如下: 在bootstrap中其他任何标签使用cl ...