当前位置: 代码迷 >> PB >> 怎么实现注册功能
  详细解决方案

怎么实现注册功能

热度:117   发布时间:2016-04-29 09:18:52.0
如何实现注册功能?
用PB做软件,如何实现注册功能?(软件需要注册才能用?)


------解决方案--------------------
你应用程序或者主窗口的open事件里写代码,判断一下注册码是否正确,不正确就弹出窗口进行注册即可
------解决方案--------------------
最好取CPU号、主板号、硬盘号等信息结合自己的算法得出注册码
------解决方案--------------------
应该是不要想了 ,如果你只是单纯的这样写的话 ,直接pbkiller 就给你搞定了 ,会用pb的人都会用这玩意
------解决方案--------------------
也可以考虑使用软件狗
------解决方案--------------------
大家知道,每当我们格式化软盘或硬盘时系统都会给它分配一个序列号,即用DOS命令dir显示出的"Volume Serial Number is 0A41-0E0A"。该序列号是随机产生的,且具有唯一性。也就是因为这个原因许多软件的测试版本利用该项技术使测试版一旦过了限定期限就不能再使用,即使将该软件重新安装也无济于事。另外,有些共享软件的注册码也是通过这个序列号来生成的。同样的方法我们也可以运用到软件的防拷贝技术。那么如何才能实现上述功能呢? 

  为了达到目的我们必须首先能够得到硬盘的序列号,其次,为了安全起见我们最好再选择一种加密算法,将加密后的硬盘的序列号作为密文公开存放,软件通过解密得到明文,即硬盘的序列号,通过将解密后的硬盘序列号和实际的硬盘序列号相比较得出程序是否合法。这一步当然是由应用程序秘密运行,用户根本不知道,从而达到软件的二次加密目的,同时也隐藏了软件的合法性识别过程,使破译者无从下手。下面就来谈谈如何具体实现。 

一、如何读取硬盘序列号 

  要读取硬盘序列号我们可以用汇编来实现,但毕竟不容易,况且也不能有效的结合到PB脚本中。在PB中我们可以通过调用Windows提供的外部函数GetVolumeInformationA()来实现。这相对来说比较简单。 


  该函数的原型为: 
  BOOL GetVolumeInformation( 
  LPCTSTR lpRootPathName, 
  LPTSTR lpVolumeNameBuffer, 
  DWORD nVolumeNameSize, 
  LPDWORD lpVolumeSerialNumber, 
  LPDWORD lpMaximumComponentLength, 
  LPDWORD lpFileSystemFlags, 
  LPTSTR lpFileSystemNameBuffer, 
  DWORD nFileSystemNameSize 

  上述原型中,参数类型只要是以"LP-"开头的表明该参数用的是长指针(Long Pointer)类型,即在PB中调用时的参数传递是通过引用传递。在8个参数中对我们真正有用的只有两个LPCTSTR lpRootPathName和LPDWORD lpVolumeSerialNumber。其中参数lpRootPathName是指向文件系统根目录的地址,我们需要用它来指明所要获取序列号的硬盘盘符;参数lpVolumeSerialNumber是返回的硬盘序列号的地址,这正是我们需要的。 

  众所周知,PB在调用任何外部函数前都要首先进行函数声明,可以将声明放在全局或局部函数声明中。具体声明如下: 

  Function Boolean GetVolumeInformationA( & 
  ref String ls_Rootpath, & 
  ref String ls_volumnename, & 
  Ulong lul_VolumeNameSize, ref Ulong lul_VolumeSerialNumber, & 
  ref Ulong lul_MaximumComponentLength, & 
  ref Ulong lul_FileSystemFlags, & 
  ref String ls_FileSystemNameBuffer, & 
  Ulong lul_FileSystemNameSize & 
  ) Library "Kernel32.dll" 

  上述声明中,"ref"指明是该参数是通过引用传递的,有关函数引用的详细内容请参见有关教程。声明完毕我们不能马上进行调用,还必需确保已为它分配足够的内存空间,即使是参数引用传递也是这样,否则的话将会出现调用错误,这跟C语言的引用调用不同,这一点往往被忽视,希望读者能够注意。也就是为什么我在调用该函数前将有些字符串参数给它预先分配了多达256个字符空间以及给一些整型类型的参数赋初始值256。完整的读取硬盘序列号的程序代码如下: 

/******************* 程序代码 ************************/ 

String ls_Rootpath, ls_volumnename 
ls_Rootpath = "C:" // 指定要得到序列号的硬盘, 

// 一般情况都是C盘,除非你能保证用户存在其它逻辑盘或物理盘 

ls_volumnename = Space(256) // 分配足够的空间,下同 
Ulong lul_VolumeNameSize 
lul_VolumeNameSize = 256 
Ulong lul_VolumeSerialNumber, lul_MaximumComponentLength, lul_FileSystemFlags 

lul_MaximumComponentLength = 256 
String ls_FileSystemNameBuffer 
ls_FileSystemNameBuffer = space(256) 
Ulong lul_FileSystemNameSize 
lul_FileSystemNameSize = 256 
beep(1) 
boolean lb_rtn 
lb_rtn = False 
lb_rtn = GetVolumeInformationA(ls_Rootpath, ls_volumnename, lul_VolumeNameSize, 
lul_VolumeSerialNumber, lul_MaximumComponentLength, lul_FileSystemFlags, 
ls_FileSystemNameBuffer, lul_FileSystemNameSize)
if lb_rtn = true then
MessageBox("提示","函数调用成功!") 
else 
MessageBox("提示","函数调用失败!") 
end if 
sle_1.text = String(lul_VolumeSerialNumber) // 得到硬盘序列号 

/********************* 结束 *************************/ 
  相关解决方案