|  | 
 
|  
 สำหรับบทความนี้จะเป็นวิธีการง่ายๆในการทำชุดลงทะเบียนโปรแกรม ซึ่งแอดมินได้สร้างโปรเจค 2 ชุดไว้ในโซลูชั่นเดียวกัน ชุดแรกก็จะเป็นเหมือนกับโปรแกรมให้ลูกค้าใช้งาน อีกส่วนคือการสร้างรหัสลงทะเบียน (เป็นโปรเจคหลัก ต้องเข้าไปเปิด Solution ในโฟลเดอร์ RegisterProgram) เวลานำไปใช้งานจริงเราต้องแยกออกจากกันน่ะครับ ...
 
 ขั้นตอนวิธีการคิดในการเข้ารหัส ...
 [1] อ่านซีเรียลนัมเบอร์ของดิสต์ อันนี้เพื่อให้ได้โค้ดง่ายๆเข้าใจไม่ยาก แอดมินให้อ่านซีเรียลนัมเบอร์แบบ Logical Disk หรือ Volume Disk ซึ่งค่านี้จะเปลี่ยนใหม่ทุกครั้งที่มีการฟอร์แมต และที่สำคัญคือสามารถเปลี่ยนค่าได้ ... ดังนั้นในการนำไปใช้งานจริงจึงไม่ปลอดภัย แอดมินแนะนำให้อ่านซีเรียลนัมเบอร์จาก Physical Disk แทน ซึ่งโค้ดในการอ่านก็อยู่ในเว็บบอร์ดแห่งนี้แหละขอรับกระผม
 
 [2] สร้างชุดกุญแจขึ้นมา 1 ชุด
 
 [3] นำ 1 กับ 2 มาทำการเข้ารหัส แน่นอนว่าแอดมินใช้วิธีการเข้ารหัสแบบง่ายๆ ท่านต้องไปศึกษาค้นคว้าเพิ่มเติมเองล่ะกันครับผม
 
 สำหรับชุดโปรแกรมที่ให้ลูกค้า หรือยูสเซอร์ใช้งาน จะต้องทำการอ่านสถานะการลงทะเบียนทุกๆครั้งที่เปิดโปรแกรมขึ้นมา โดยอ่านค่าตัวแรกคือซีเรียลนัมเบอร์ของดิสต์ (ป้องกันการเปลี่ยนแปลงค่าจากผู้ใช้) จากนั้นไปอ่านค่า Product Key หรือรหัสลงทะเบียนที่ได้ทำการ Registry เอาไว้ใน RegEdit หากไม่เจอค่าใดๆ แสดงว่ายังไม่มีการลงทะเบียน ก็ระบุ blnDemo = True หรือยังเป็นชุดทดลองอยู่นั่นเอง แต่หากมีค่า Product Key ก็เอามาทำการเข้ารหัส (เหมือนข้อ 3 ด้านบน) ด้วยซีเรียลนัมเบอร์ฮาร์ดดิสต์กับกุญแจที่กำหนดไว้ แล้วนำมาเปรียบเทียบค่า Product Key ที่ได้ก็เป็นอันจบ ...
 
 การเลือกโปรเจคที่จะให้ทำงานเริ่มต้น (StartUp Project)
 
  
 การ Registry ค่าต่างๆ การที่แอดมินนำไปไว้ที่ HKEY_CURRENT_USER ก็เพราะว่า Windows 10 มันมีการป้องกันสูง หากนำไปไว้ที่ LOCAL MACHINE มักมีปัญหาในการเขียนค่าลงไป
 
  
 มาดูโค้ดในส่วนของการสร้างรหัสลงทะเบียน ... (RegisterProgram) ...
 คัดลอกไปที่คลิปบอร์ดPublic Class frmGenKeyMaker
    '// เลขชุดเหมือนกุญแจที่ต้องนำมาเข้ารหัสต้องตั้งค่าให้ตรงกัน
    Dim ProgramID As UInt32 = 1234567890
    Private Sub btnGenKey_Click(sender As System.Object, e As System.EventArgs) Handles btnGenKey.Click
        Try
            '// ค่านี้ต้องได้รับมาจากลูกค้า
            Dim ProductNumber As UInt32 = UInt32.Parse(txtProductNumber.Text)
            txtProductKey.Text = Encrypt(ProgramID, ProductNumber)
        Catch ex As Exception
            txtProductKey.Clear()
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    '/ Simple encryption and decryption.
    Private Function Encrypt(ByVal seed As UInt32, ByVal value As UInt32) As UInt32
        Dim rand As New Random(CInt(seed \ 2))
        Return (value Xor CUInt(UInt32.MaxValue * rand.NextDouble()))
    End Function
    Private Sub frmGenKeyMaker_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        txtProductID.Text = ProgramID
        txtProductNumber.Text = GetDriveVolumeSerialNumber()
    End Sub
    Private Function GetDriveVolumeSerialNumber() As String
        Dim DriveSerial As Long
        Dim FSO As Object, Drv As Object
        '/ Create a FileSystemObject object
        FSO = CreateObject("Scripting.FileSystemObject")
        Drv = FSO.GetDrive(FSO.GetDriveName(AppDomain.CurrentDomain.BaseDirectory))
        With Drv
            If .IsReady Then
                DriveSerial = .SerialNumber
            Else    '"Drive Not Ready!"
                DriveSerial = -1
            End If
        End With
        '/ Clean up
        Drv = Nothing
        FSO = Nothing
        GetDriveVolumeSerialNumber = Math.Abs(DriveSerial) 'Hex(Math.Abs(DriveSerial))
    End Function
End Class
 
 มาดูโค้ดในส่วนของผู้ใช้งานในการลงทะเบียน ... (CustomerProgram) ...
 
 คัดลอกไปที่คลิปบอร์ดPublic Class frmCustomerProgram
    '// กำหนดชื่อ Section
    Dim SectionName As String = "SampleProgram"
    '// ตัวอย่างชุดตัวเลขเพื่อทำการเข้ารหัส (เหมือนกุญแจ)
    Dim ProgramID As UInt32 = 1234567890
    '// รหัสลงทะเบียนโปรแกรม
    Dim ProductKey As String
    '// Volume Disk
    Dim ProductNumber As String
    Private Sub frmCustomerProgram_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        Me.Dispose()
        GC.SuppressFinalize(Me)
        Application.Exit()
    End Sub
    Private Sub frmCustomerProgram_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Call Register()
    End Sub
    Sub Register()
        '// อ่านค่า Volume Disk ใหม่ เผื่อมีการแก้ไขเปลี่ยนแปลงค่าใน Registry
        ProductNumber = GetDriveVolumeSerialNumber()
        '// อ่านรหัสปลดล็อคโปรแกรมจาก Registry
        ProductKey = ReadAppRegistry(SectionName, "ProductKey", "")
        '// หากไม่มีค่า ProductKey แสดงว่ายังไม่เคยลงทะเบียนโปรแกรม
        If IsNothing(ProductKey) Or Len(ProductKey) = 0 Then
            '// กำหนดให้เป็น DEMO อยู่
            blnDemo = True
            '// กรณีที่เกิดการแก้ไขค่า Volumn Disk ต้องใช้ค่าที่เราอ่านได้เอง
            Call WriteAppRegistry(SectionName, "ProductNumber", ProductNumber)
            '// ไม่มีการลงทะเบียน
            Call WriteAppRegistry(SectionName, "ProductKey", "")
            Me.Text = Application.ProductName & " [Demo Version]"
            Exit Sub
            '// แสดงว่ามี ProductKey
        Else
            '// เข้ารหัสค่า ProductKey ที่มาจาก Registry โดยมี ProgramID (กุญแจ)
            Dim ActivateKey As UInt32 = Encrypt(ProgramID, CUInt(ProductNumber))
            '// หากค่าเท่ากัน แสดงว่าลงทะเบียนโปรแกรมถูกต้อง ไม่ต้องทำการเขียนข้อมูลลง Registry
            '/ ---------------------------------------------------------------
            If ActivateKey = ProductKey Then
                blnDemo = False
                Me.Text = Application.ProductName & " [Version: " & Application.ProductVersion.Substring(0, 4) & "]"
                '// อาจจะมีการเปลี่ยนแปลงค่าใน Registry ก็เลยทำให้ค่าที่ได้ไม่เท่ากัน
            Else
                blnDemo = True
                '// เขียนข้อมูล Volume Disk กลับลงไปใน Registry อีกครั้ง
                Call WriteAppRegistry(SectionName, "ProductNumber", ProductNumber)
                '// ให้ค่ารหัสลงทะเบียนเป็นค่าว่างเปล่า
                Call WriteAppRegistry(SectionName, "ProductKey", "")
                Me.Text = Application.ProductName & " [Demo Version]"
            End If
        End If
    End Sub
    Private Sub btnRegister_Click(sender As System.Object, e As System.EventArgs) Handles btnRegister.Click
        frmRegister.ShowDialog()
    End Sub
End Class
ฟอร์มในการลงทะเบียนโปรแกรม ...
 
 คัดลอกไปที่คลิปบอร์ดPublic Class frmRegister
    '// กำหนดชื่อ Section
    Dim SectionName As String = "SampleProgram"
    '// ตัวอย่างชุดตัวเลขเพื่อทำการเข้ารหัส (เหมือนกุญแจ)
    Dim ProgramID As UInt32 = 1234567890
    '// รหัสลงทะเบียนโปรแกรม
    Dim ProductKey As String
    '// Volume Disk
    Dim ProductNumber As String
    Private Sub frmRegister_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        Me.Dispose()
        GC.SuppressFinalize(Me)
    End Sub
    Private Sub frmRegister_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        '// อ่านค่า Volume Disk อีกรอบ
        txtProductNumber.Text = GetDriveVolumeSerialNumber()
        '// โหลดค่ารหัสลงทะเบียนมาเก็บไว้
        txtProductKey.Text = ReadAppRegistry(SectionName, "ProductKey", "")
        '// blnDemo จะถูกโหลดตั้งแต่ฟอร์มหลักที่เรียกมา (frmCustomerProgram.vb)
        If Not blnDemo Then
            txtProductKey.Enabled = False
            btnOk.Enabled = False
            btnCancel.Text = "Close"
        End If
    End Sub
    Private Sub btnCancel_Click(sender As System.Object, e As System.EventArgs) Handles btnCancel.Click
        Me.Close()
    End Sub
    Sub Register()
        ProductNumber = txtProductNumber.Text
        '// อ่านค่า ProductKey จาก Registry
        ProductKey = ReadAppRegistry(SectionName, "ProductKey", "")
        '// ยังไม่ได้ลงทะเบียน
        If Len(ProductKey) = 0 And txtProductKey.Text.Trim.Length = 0 Then
            blnDemo = True
            frmCustomerProgram.Text = Application.ProductName & " [Demo Version]"
            txtProductKey.Focus()
            '// ตรวจสอบค่าที่ป้อนเข้ามาใน ProductKey
        ElseIf txtProductKey.Text.Trim.Length <> 0 Then
            '// เข้ารหัส ProgramID (กุญแจ) ร่วมกับ ProductNumber (Volume Disk)
            Dim ActivateKey As UInt32 = Encrypt(ProgramID, CUInt(ProductNumber))
            '// เปรียบเทียบค่าที่ได้จากการเข้ารหัสใหม่ (ActivateKey) และค่าที่ผู้ใช้ป้อนเข้ามา
            If ActivateKey = CUInt(txtProductKey.Text) Then
                '// ถูกต้อง ...
                blnDemo = False
                Call WriteAppRegistry(SectionName, "ProductNumber", ProductNumber)
                Call WriteAppRegistry(SectionName, "ProductKey", txtProductKey.Text.Trim)
                MessageBox.Show("Registration Complete.", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Information)
                frmCustomerProgram.Text = Application.ProductName & " [Version: " & Application.ProductVersion.Substring(0, 4) & "]"
                Me.Close()
            Else
                '// ลงทะเบียนมั่ว
                blnDemo = True
                MessageBox.Show("Product Key is not correct.", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                frmCustomerProgram.Text = Application.ProductName & " [Demo Version]"
                txtProductKey.Focus()
            End If
        End If
    End Sub
    Private Sub btnOk_Click(sender As System.Object, e As System.EventArgs) Handles btnOk.Click
        Call Register()
    End Sub
End Class
โมดูลในส่วนของฟังค์ชั่นต่างๆ ...
 
 คัดลอกไปที่คลิปบอร์ดModule modFunction
    '// กำหนดให้เป็นตัวแปรแบบ Public สามารถมองเห็นได้ทั้งโปรเจค 
    '// เพื่อระบุว่าเป็นการลงทะเบียนหรือไม่
    '// blnDemo = False ลงทะเบียนเรียบร้อย (ไม่ใช่ชุดทดลอง)
    '// blnDemo = True ยังไม่ได้ลงทะเบียน (ยังเป็นชุดทดลองอยู่)
    Public blnDemo As Boolean = True
    ' / -----------------------------------------------------------------------------------------------
    ' / Registry with VB.NET function
    ' / Function read original font style from Registry and return its.
    Public Function ReadAppRegistry(SectionName As String, _
        KeyName As String, _
        KeyValue As String _
    ) As String
        ' Application Title ... 
        Dim AppTitle As String = My.Application.Info.Title
        '// Check exist KeyName, If not have to create new value by default.
        If GetSetting(AppTitle, SectionName, KeyName) = "" Then _
            Call SaveSetting(AppTitle, SectionName, KeyName, KeyValue)
        ' Return Value
        ReadAppRegistry = GetSetting(AppTitle, SectionName, KeyName)
    End Function
    ' / -----------------------------------------------------------------------------------------------
    ' / Save all font style into Registry, No return The use of sub program.
    ' / Registry with VB.NET function
    Public Sub WriteAppRegistry(SectionName As String, _
        KeyName As String, _
        KeyValue As String _
    )
        ' Application Title ... 
        Dim AppTitle As String = My.Application.Info.Title
        Call SaveSetting(AppTitle, SectionName, KeyName, KeyValue)
    End Sub
    '/ Simple encryption and decryption.
    Public Function Encrypt(ByVal seed As UInt32, ByVal value As UInt32) As UInt32
        Dim rand As New Random(CInt(seed \ 2))
        Return (value Xor CUInt(UInt32.MaxValue * rand.NextDouble()))
    End Function
    Public Function GetDriveVolumeSerialNumber() As String
        Dim DriveSerial As Long
        Dim FSO As Object, Drv As Object
        '/ Create a FileSystemObject object
        FSO = CreateObject("Scripting.FileSystemObject")
        Drv = FSO.GetDrive(FSO.GetDriveName(AppDomain.CurrentDomain.BaseDirectory))
        With Drv
            If .IsReady Then
                DriveSerial = .SerialNumber
            Else    '"Drive Not Ready!"
                DriveSerial = -1
            End If
        End With
        '/ Clean up
        Drv = Nothing
        FSO = Nothing
        GetDriveVolumeSerialNumber = Math.Abs(DriveSerial) 'Hex(Math.Abs(DriveSerial))
    End Function
End Module
ดาวน์โหลดโค้ดต้นฉบับแบบเต็ม VB.NET (2010) ได้ที่นี่ ...
 
 | 
 
xขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึงคุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน  |