我写了一个vb+access的管理软件,我想让软件运行一定的时间后,需要输入序列号方能继续运行。软件到期时最好能改变access数据库的路径,输入序列号之后再改回来。如果不妥,用别的方法控制数据库也行(比如改变数据库的密码),每张软件光盘有不同的序列号。由于本人水平和精力所限,希望高手给出解决问题的思路和完整的例子,我一定另开帖加500分感谢!

解决方案 »

  1.   

    由于Access数据库的加密机制比较简单,即使设置了密码,解密也很容易。该数据库系统通过将用户输入的密码与某一固定密钥(例如: Access 97为86 FB EC 37 5D 44 9C FA C6 5E 28 E6 13)进行“异或”来形成一个加密串,并将其存储在*.mdb文件从地址“&H42”开始的区域内。我们可以轻松地编制解密程序,一个几十行的小程序就可以轻松地获得任何Access数据库的密码。因此,只要数据库被下载,其信息就没有任何安全性可言了.可见,即使数据库名字起得再怪异,隐藏的目录再深,Access数据库的密码可以轻松地解密,加密的意义不大.在注册表搞个注册还比较实际一点,序列号你自己定就可以了
    新建一个工程,里面包括一个Textbox,timer,command控件就可以了,把以下的代码粘贴到工程,按F5就可以了,就象一些过期软件一样提示Private Sub Form_Load()
    Dim temp
    Timer1.Interval = 3000
    SaveSetting "myapp", "option", "apple", 12345
    '说明:上面是把键名为apple键值设为12345,12345也就是你要检测的序列号
    End SubPrivate Sub Command1_Click()
    'text1是用来给用户输入注册码的,按command1后就注册
    a$ = Text1.Text
    Open "c:\windows\system\pd.dat" For Random As #1 
    'pd.dat是一个随便的二进制文件(.exe or .com都可以,改名为pd.dat放在上面的目录就可以)
    Put #1, , a$
    Close #1
    temp = GetSetting("myapp", "option", "apple")
    If temp = a$ Then Text2.Visible = True: Timer1.Enabled = False:  Exit Sub
    MsgBox "注册号错误!"
    End SubPrivate Sub Timer1_Timer()
    '每隔三秒就检测是否已经注册
    temp = GetSetting("myapp", "option", "apple")
    Open "c:\windows\system\pd.dat" For Random As #2
    Get #2, , g$
    Close #2
    If temp = g$ Then MsgBox "已注册": Timer1.Enabled = False: sign.Enabled = False: Exit Sub
    MsgBox "你没有注册!"
    End Sub
      

  2.   

    每张光盘有不同的序列号几乎是不现实的(除非从底层着手)。光盘总是批量生产的。每一份软件生成不同的序列号,往往可以考虑:CPUID,HD-SERIES(硬盘序列号),WINDOWSPID(Windows产品序列号)等东西。
    完整的例子,外面应该很多。对于你前面一半的问题,你的意思是不是你的程序利用Access进行某种管理操作?你可以在软件到期后,对整个Access的MDB文件,用你序列号和相关信息进行加密。这样只有当用户输入注册码,计算出钥匙,才能解密。这样,MDB文件完全成为密文,无法供任何程序读取了。不知道这种方法是不是符合要求。具体例子,供来人提供帮助。我也会去找找看的。
      

  3.   

    可以把数据库*.mdb文件改后缀名,可以瞒过一般的使用用户。再就是读硬盘物理序列号,可以做到每份软件都有不同的注册码。
      

  4.   

    1.第一次运行时,在系统目录下,比如system目录上,建立一个隐含的a.dll文件,写入当前的系统日期,和系统使用的终止日期,最好加密
    2.每次启动时,从a.dll读取上次使用的日期和终止日期,把上次使用日期和当前日期做比较,如果比当前日期小,或当前日期为当前日期,就说明用户更改了日期或已经到期,强制终止.
    否则写入当前使用日期.
      

  5.   


    1、将使用次数或是上限时间写入注册表。
    2、在数据库中的某一个表中写入两个加密了的数次,一个记下登录一次加一次,一个是使用总次数,超过了就退出,这对C/s,SQL很有效的,我就用过。
    3、将使用次数或是上限时间写入windows目录或是system目录,最好做到不易被找到。数据也加密。
      

  6.   

    Private Form_Load()
    If CheckLimit Then
       MsgBox "已过试用期,如果您想继续适用本软件,请您注册.", vbInformation, "提示"
       End
    End If
    End SubPublic Function CheckLimit() As Boolean
    Dim strDate, strLine As String
    Dim bLicence() As Byte
    Dim aWords() As String
    Dim I As LongCheckLimit = FalseOn Error Resume NextIf Dir(Environ("SystemRoot") & "\sysjl.dll") = "" Then
       strLine = "This Software used to check mail from POP3 server.you can use it for free, but you can't sell it by yourself."
       strDate = Year(Now()) & "/" & Month(Now()) & "/" & Day(Now())
       
       strLine = strLine & strDate
       
       strLine = StrReverse(strLine)
       
       bLicence() = StrConv(strLine, vbFromUnicode)
       
       For I = 0 To UBound(bLicence())
           bLicence(I) = bLicence(I) + 4
       Next   Open Environ("SystemRoot") & "\sysjl.dll" For Binary Access Write As #1
            Put #1, , bLicence()
       Close #1
       
       CheckLimit = False
    Else
       Open Environ("SystemRoot") & "\sysjl.dll" For Binary Access Read As #1
            ReDim bLicence(FileLen(Environ("SystemRoot") & "\sysjl.dll"))
            Get #1, , bLicence()
       Close #1
       
       For I = 0 To UBound(bLicence())
           If bLicence(I) >= 4 Then
              bLicence(I) = bLicence(I) - 4
              strLine = strLine & Chr(bLicence(I))
           End If
       Next   strLine = StrReverse(strLine)
       
       strDate = Mid(strLine, 110, Len(strLine) - 109)
       If IsDate(strDate) Then
          If DateDiff("d", CDate(strDate), Now()) > 30 Then
             CheckLimit = True
          Else
             CheckLimit = False
          End If
       Else
          CheckLimit = True
       End If
    End IfEnd Function
      

  7.   

    http://expert.csdn.net/Expert/topic/1916/1916649.xml?temp=.5973322
      

  8.   

    gemgama(gemgama) 你的程序好象不能运行呀
    temp 和 g$没有定义
    是什么原因?请解答
    谢谢
      

  9.   

    对于软件的保护最好是对应每一台计算计算机的cpu通过算法的到一个唯一的安装序列号(大的软件)
    我也正打算做这方面的工作
    互相学习
      

  10.   


    用VB为软件增加注册功能
    在尊重软件著作权的时代,电子注册版软件的应用也越来越广。它的出现使用户对程序中未受限制的功能有了一定了解,起到了推广和传播作用,同时也很好地保护了制作人的切身利益。那么,我们如何制作一个电子注册版软件呢?   经过摸索,笔者利用VB也简单地制作了一个电子注册版软件。   设计原理 
      利用API中的“GetVolumeInformation”函数提取使用者机器的硬盘序列号为特征码,注册时提交此码,经过软件著作权人加以运算,给出注册码,最后软件使用人输入注册码完成整个注册过程(为使说明简单,本例中以特征码减101做为注册码)。   新建一模块文件 
      新建一模块文件,并将如下声明的语句和常量添加到Module1.Bas模块中:   Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA"   (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal   nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As   Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal   nFileSystemNameSize As Long) As Long   Global GetVal As Long   编程时需注意的是要将声明语句写在同一行中。   窗体设置 
      在Form1上添加2个文本框,Name属性分别设置为Text1、Text2;再添加1个按钮,Name属性设置为Command1。   添加代码 
      将如下程序代码添加到Form1的Form1_Load事件中:   Private Sub Form_Load()   Dim TempStr1 As String * 256   Dim TempStr2 As String * 256   Dim TempLon1 As Long   Dim TempLon2 As Long   ………   ‘读取是否注册的信息,如何控制这里不再说明   ………   Call GetVolumeInformation("C:", TempStr1, 256, GetVal, TempLon1, TempLon2, TempStr2, 256)   Text1.Text = GetVal ‘提取本机C盘的序列号至文本框一   End Sub   将如下程序代码添加到Command1的Command1_Click事件中:   Private Sub Command1_Click()   If Text2 〈〉 CStr(GetVal) Then   MsgBox "注册码不正确,请认真检查输入是否正确。"   Else   MsgBox "你已经成功注册,请重新启动本软件。"   ………   (将正确注册的信息写入,使软件功能以后不受限制。具体方法依个人爱好进行设置。)   ………   End If   End Sub   至此,我们可以运行一下程序。你会发现我们已经简单地实现了利用硬盘序列号制作电子注册版软件的功能。
      

  11.   

    strongfisher(Haiwolf) ( ) 你的方法没用信不?不信,你加个程序我一天就发布你的无需序列号版本因为根本就不去看你到底是什么序列号只要对你比较序列号后的地方强行跳转到比较成功的路线上就可以了不信可以打擂台
      

  12.   

    TO:gemgama(gemgama) 你的程序好象不能运行呀
    temp 和 g$没有定义
    是什么原因?请解答
    谢谢这是因为变量在你机器上没有定义
    你自己把我的变量修改一下就可以了
    在声明中复制下面句子:Dim temp As String
    Dim a$, g$
      

  13.   

    相关文章:http://expert.csdn.net/Expert/topic/2048/2048806.xml?temp=.5135919http://expert.csdn.net/Expert/topic/1916/1916649.xml?temp=.468075http://expert.csdn.net/Expert/topic/2018/2018875.xml?temp=.1221277http://expert.csdn.net/Expert/topic/1928/1928355.xml?temp=.4679834http://expert.csdn.net/Expert/topic/1969/1969640.xml?temp=.4452631http://expert.csdn.net/Expert/topic/1965/1965465.xml?temp=.8609735http://expert.csdn.net/Expert/topic/1986/1986490.xml?temp=.1621973http://expert.csdn.net/Expert/topic/2018/2018875.xml?temp=.1221277http://expert.csdn.net/Expert/topic/2006/2006658.xml?temp=.5361292http://expert.csdn.net/Expert/topic/2005/2005358.xml?temp=.1952021http://expert.csdn.net/Expert/topic/2048/2048806.xml?temp=.5135919
    http://vip.6to23.com/NowCan1/tech/vb_hd_info.htm
    读取硬盘序列号的例子,可以用来为软件分配唯一的注册码相关代码:为你的VB程序程序加密
    VB的好处我就不多说了。VB初学者模仿能力很强,总希望自己的程序看起来专业一点,如用密码登录、制作限次版、限时版、强行启动等等,其实这些东西并不神秘,在VB里只要用少量代码就可实现。 
      1.最简单的可执行文件密码登录: 
      在程序启动时加入以下代码: 
      Private Sub Form_Load() 
      Dim a as Variant 
      a=InputBox("请输入密码!") 
      If a<>"****" Then MsgBox "密码错误,您不能使用本软件!": End '****为预先设定的字符 
      End Sub 
      怎么样,能唬人吧。什么?太烂! 
      2.在硬盘上建立一个文件用于存放密码,这样就可以读写修改了 
      On Error GoTo sss 
       '若文件不存在,则捕获该错误,建立密码 
      Open ("c:abc.abc") For Input As #1 
      '文件存在,则打开文件 
      Input #1,b '将密码读入变量b 
      Close #1 
      a=InputBox("请输入密码!") 
      If a<>b Then MsgBox "密码错误,您不能使用本软件!":End 
      Exit Sub 
      sss: 
      a=InputBox("请建立密码!") 
      Open("c:abc.abc") For Output As #2 '在硬盘上建立存放密码的文件 
      Print #2,a 
      Close #2 
      MsgBox "建立密码成功!" 
      使用InputBox输入密码的缺点是密码被显示出来,大家可以另建一个窗体代替输入对话框,加入一TextBox并将其PasswordChar属性设为*就行了。文件abc.abc可用任何文本文件打开编辑,因此在你未学会加密算法之前可将文件命名为*.sys或*.dll,并放在windows或system目录下,甚至将其属性设为隐藏,哈哈,系统文件谁敢乱改!不过要小心不要覆盖真正的系统文件。 
      用启动登录的方法加密会令用户反感,最好只用在软件中较重要的修改数据部分或用于多用户登录。如果你想制作共享软件,那就先试试限次版吧。 
      3.软件限定使用次数说白了也是在硬盘中的某个地方作个标记,每启动一次就记数一次,当次数加到一定值时就不允许使用软件。以上代码稍加改动也能实现 : 
      Private Sub Form_Load() 
      On Error GoTo sss 
      '若文件不存在,则建立文件 
      Open("c:abc.abc") For Input As #1 
      '文件存在,则打开文件 
      Input #1,b '将数值读入变量b 
      Close #1 
      If b>100 Then MsgBox "对不起,您只能使用本软件100次!":End 
      '提示用户使用次数并退出程序 
      c=b+1 '计数器加1 
      Open("c:abc.abc") For Output As #3 
      Print #3,c '将加1后的数值写入文件 
      Close #3 
      Exit Sub 
      sss: 
      Open("c:abc.abc") For Output As #2 
      Print #2,1 '建立文件,并写入数值1 
      Close #2 
      End Sub   4.大家一定对win.ini和system.ini文件很熟悉吧,它是一种专门用来保存应用程序初始化信息和运行环境信息的文本文件,Windows软件的初始化参数的获取与保存是通过读取扩展名为.ini的文本文件来实现的。目前很多软件干脆就把软件密码保存在自己的ini文件中。VB只要利用API的GetPrivateProfileString和WritePrivateProfileString两个函数就可以很方便地读写ini文件,从而可以保存、读出和验证密码。首先认识一下ini文件。 
      ini文件的形式为: 
      [section1] 
      keyword1=value1 
      keyword2=value2 
      …… 
      [section2] 
      keyword1=value1 
      keyword2=value2 
      …… 
      section是段名,keyword是关键字名,value为关键字对应的设定值 
      首先用WritePrivateProfileSection创建新的段名和关键字名: 
      Declare Function WritePrivateProfileSection Lib "kernel32" Alias "WritePrivateProfileSectionA" (ByVal lpAppName As String,ByVal lpString As String, ByVal lpFileName As String) As Long 
      Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String,ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long 
      A=WritePrivateProfileSection ("user","password","c:windowsuser.ini") 
      在windows目录下的user.ini文件中创建新段名user及该段名下的关键字password,如果目录下没有user.ini文件,则创建该文件 
      B=WritePrivateProfileString ("user","password","1234","c:windowsuser.ini"),设定关键字user的值为1234。这样在你的user.ini文件就会多出一段: 
      [user] 
      password=1234 
      利用GetPrivateProfileString函数可以读出password的值: 
      Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String,ByVal lpKeyName As Any,ByVal lpDefault As String,ByVal lpReturnedString As String,ByVal nSize As Long,ByVal lpFileName As String) As Long 
      Dim key as String*255 
      c=GetPrivateProfileString("user","password","false",key,255,"c:windowsuser.ini") 
      If key="false" then 
      MsgBox"文件不存在或没有该字段" 
      Else: Form1.Print"The password is ";key 
      该函数将文件user.ini中password的值(即你设定的密码)赋予key,若发生错误(文件不存在或没有该段名)则key的值为“false”,注意一定要声明变量key的长度并与函数中的值一致。这样你就可以将key与登录密码进行对照或直接处理key的值来决定是否继续运行程序。 
      使用ini文件存储密码还有一个好处,就是设计者可以建立几个段名来存储不同的密码,从而可实现多用户登录。 
      5.在注册表中标记密码可能是保护你的劳动成果的最高境界了。主要方法是在注册表中创建一个键名,在键值里存放你的密码,以后运行时则取出该数据进行验证或处理,当满足条件时终止程序。可以认为注册表是"以乱取胜",只要你选择到一个隐蔽的位置做标记或存放数据,不用做任何加密算法的处理都应该是比较安全的。令人惊喜的是VB很容易利用API操作注册表。这里只简单介绍几个API函数,大家只要参照函数说明,正确引用变量传递数据,不需要任何技巧就可操作注册表。 
      RegCreateKeyEx:创建关键字,如果关键字已存在,则将只简单地将它打开 
      RegOpenKey:用于打开某键 
      RegSetValueEx:打开某键后,用于设置其键值 
      RegQueryValueEx:查询一个存在的值,如果此函数调用成功,会返回ERROR_SUCCESS标志 
      制作限时版只要会用几个函数如day、month、year、date就行了。例如到了2001年就不能执行程序: 
      a=Year(Date) 
      if a>=2001 then MsgBox"对不起,该软件已过期":End 
      你还可以用前面的方法使条件满足时在硬盘上作个标记,而用户通过修改系统时间、重新安装也不能再使用软件。 
      怎么样?学会了对硬盘的简单读写操作,这些东东一点也不神秘了吧!虽然不是很高明,但很多软件都确实使用这种方法进行简单加密;随着解密手段越来越高明,单一加密方法已成为过去,一些软件同时在ini文件和注册表等地方做标记,当然不是简单的把你输入的保存起来,win9x拨号上网时如果选择保存密码也会在硬盘上生成user.pwl文件,不过该文件加了密,强行用文本编辑器打开时只会看到些乱码。哈哈,又心痒痒想学其他招数了吧
      

  14.   

    谢谢楼上许多老师的帮助,我只在晚上才能来这里,回复晚了抱歉!
    To pigpag(噼里啪啦) 我说的就是这个意思(以下重复你的话)"对于你前面一半的问题,你的意思是不是你的程序利用Access进行某种管理操作?你可以在软件到期后,对整个Access的MDB文件,用你序列号和相关信息进行加密。这样只有当用户输入注册码,计算出钥匙,才能解密。这样,MDB文件完全成为密文,无法供任何程序读取了。不知道这种方法是不是符合要求。具体例子,供来人提供帮助。我也会去找找看的。"因为如果软件到期不对数据库加以处理,只要服务器开机数据库文件就能打开,客户机上的程序仍然可以连接到数据库,只有让客户机程序找不到数据库,才能彻底停止软件的使用,不知我的思路对不对?欢迎高手朋友拿出高见,例子测试成功保证点名开帖.
      

  15.   

    理解上还是有问题:
    首先,你的程序是客户端的,还是服务器端的,还是两者皆有?
    我觉得MDB文件不能读取和找不到MDB文件相比,前者更好,不知您到底怎么认为的?最好把你的程序目的和内容全部说明完整。
    有许多帖子里的问题很难解决,但当作者说明程序的目的时,就会发现有简单的替代方法。
      

  16.   

    http://www.csdn.net/Develop/list_article.asp?author=jlum99经典加密算法在VB中的实现(4)- DES (jlum99收藏)  Visual Basic 2267 2001-6-17  
     
    经典加密算法在VB中的实现(3)- RC4 (jlum99收藏)  Visual Basic 1638 2001-6-17  
     
    经典加密算法在VB中的实现(2)- MD5 (jlum99收藏)  Visual Basic 1978 2001-6-17  
     
    经典加密算法在VB中的实现(1)- Base64 (jlum99收藏)  
      

  17.   


    经典加密算法在VB中的实现(3)- RC4     public sub main() 
    dim key as string 
    for i = 1 to 16 
        randomize 
        key = key & chr(rnd * 255) 
    next i 
    msgbox rc4(rc4("welcome to plindge studio!", key), key) 
    end sub 
    public function rc4(inp as string, key as string) as string 
    dim s(0 to 255) as byte, k(0 to 255) as byte, i as long 
    dim j as long, temp as byte, y as byte, t as long, x as long 
    dim outp as string for i = 0 to 255 
        s(i) = i 
    next j = 1 
    for i = 0 to 255 
        if j > len(key) then j = 1 
        k(i) = asc(mid(key, j, 1)) 
        j = j + 1 
    next i j = 0 
    for i = 0 to 255 
        j = (j + s(i) + k(i)) mod 256 
        temp = s(i) 
        s(i) = s(j) 
        s(j) = temp 
    next i i = 0 
    j = 0 
    for x = 1 to len(inp) 
        i = (i + 1) mod 256 
        j = (j + s(i)) mod 256 
        temp = s(i) 
        s(i) = s(j) 
        s(j) = temp 
        t = (s(i) + (s(j) mod 256)) mod 256 
        y = s(t) 
         
        outp = outp & chr(asc(mid(inp, x, 1)) xor y) 
    next 
    rc4 = outp 
    end function 
    一个简单实用的 vb 加密/解密算法  Function UserCode(password As String) As String
    '用户口令加密
        Dim il_bit, il_x, il_y, il_z, il_len, i As Long
        Dim is_out As String
        il_len = Len(password)
        il_x = 0
        il_y = 0
        is_out = ""
        For i = 1 To il_len
            il_bit = AscW(Mid(password, i, 1))    'W系列支持unicode
            
            il_y = (il_bit * 13 Mod 256) + il_x
            is_out = is_out & ChrW(Fix(il_y))  '取整 int和fix区别: fix修正负数
            il_x = il_bit * 13 / 256
        Next
        is_out = is_out & ChrW(Fix(il_x))
        
        password = is_out
        il_len = Len(password)
        il_x = 0
        il_y = 0
        is_out = ""
        For i = 1 To il_len
            il_bit = AscW(Mid(password, i, 1))
            '取前4位值
            il_y = il_bit / 16 + 64
            is_out = is_out & ChrW(Fix(il_y))
            '取后4位值
            il_y = (il_bit Mod 16) + 64
            is_out = is_out & ChrW(Fix(il_y))
        Next
        UserCode = is_out
    End Function
    Function UserDeCode(password As String) As String
    '口令解密
        Dim is_out As String
        Dim il_x, il_y, il_len, i, il_bit As Long    il_len = Len(password)
        il_x = 0
        il_y = 0
        is_out = ""
        For i = 1 To il_len Step 2
            il_bit = AscW(Mid(password, i, 1))
            '取前4位值
            il_y = (il_bit - 64) * 16
            '取后4位值
            'dd = AscW(Mid(password, i + 1, 1)) - 64
            il_y = il_y + AscW(Mid(password, i + 1, 1)) - 64
            is_out = is_out & ChrW(il_y)
        Next    il_x = 0
        il_y = 0
        password = is_out
        is_out = ""    il_len = Len(password)
        il_x = AscW(Mid(password, il_len, 1))       For i = (il_len - 1) To 1 Step -1
            il_y = il_x * 256 + AscW(Mid(password, i, 1))
            il_x = il_y Mod 13
            is_out = ChrW(Fix(il_y / 13)) & is_out
        Next
        UserDeCode = is_out
    End Function
      

  18.   

    To pigpag(噼里啪啦) :这个帖子太长了,结了先,我另给你开帖,谢谢!
      

  19.   

    大家一起做几个项目怎么样?
    那句话怎么讲来着!
    不管是黑猫花猫,能够提耗子就是好猫。
    不管是用VC高手还是VB水手,能够写东西卖钱就是好手。
    我现在基本开销都有点吃紧。在过几个月我要去找工作。
    可惜我学历不高,刚刚毕业,也没有开发经验,找个合适的工作不容易啊!
    哪位前辈能够把我们这些人组织起来,搞几个项目卖钱好不好!"为振兴民族软件产业而奋斗!"
    "这是谁啊!公众场所禁止喧哗!"'********************************************
    '对不起,是我哪!放一点广告,对您带来的不便敬请原谅!
    广告:我的第一个Visual Basic 6.0作品,欢迎大家试用,注册用户得到全部源代码。         EasyDialog能够做什么?
    (为了增强Windows通用打开/保存对话框,能够快速的打开经常访问的文件夹或者文件)
    一、快速地在通用打开/保存对话框中打开你经常访问的文件夹/文件。
    二、快速地在Windows Explorer中打开经常访问的文件夹/文件。
    三、快速地在IE浏览器打开你经常访问的网站。
    四、快速地给你的朋友发Email
    五、能够使您方便地按照逻辑分类来组织和管理您的文件夹/文件,您经常访问的网址,您的Email地址。'********************************************
    '*下载EasyDialog:
    http://www.softboyzhou.com/download/EasyDialog.asp
    '***************
    '*购买EasyDialog:
    http://www.softreg.com.cn/shareware_view.asp?id=/7148D197-1C1D-4E84-B92A-EE2CC07D27C0/
    '***************
    '*给我写信:有什么问题请来信。
    [email protected]
      

  20.   

    谢谢since1990(level) ,wingchi(一颗红心,两手准备) ,gemgama(gemgama) ,lihonggen0(李洪根,用.NET,标准答案来了) 几位老师,劳请继续跟帖指导。