[VB.NET] วิธีการสร้างชุดลงทะเบียนโปรแกรม (Registration)
http://www.g2gnet.com/webboard/images/vbnet/registermain.pngสำหรับบทความนี้จะเป็นวิธีการง่ายๆในการทำชุดลงทะเบียนโปรแกรม ซึ่งแอดมินได้สร้างโปรเจค 2 ชุดไว้ในโซลูชั่นเดียวกัน ชุดแรกก็จะเป็นเหมือนกับโปรแกรมให้ลูกค้าใช้งาน อีกส่วนคือการสร้างรหัสลงทะเบียน (เป็นโปรเจคหลัก ต้องเข้าไปเปิด Solution ในโฟลเดอร์ RegisterProgram) เวลานำไปใช้งานจริงเราต้องแยกออกจากกันน่ะครับ ...
ขั้นตอนวิธีการคิดในการเข้ารหัส ...
อ่านซีเรียลนัมเบอร์ของดิสต์ อันนี้เพื่อให้ได้โค้ดง่ายๆเข้าใจไม่ยาก แอดมินให้อ่านซีเรียลนัมเบอร์แบบ Logical Disk หรือ Volume Disk ซึ่งค่านี้จะเปลี่ยนใหม่ทุกครั้งที่มีการฟอร์แมต และที่สำคัญคือสามารถเปลี่ยนค่าได้ ... ดังนั้นในการนำไปใช้งานจริงจึงไม่ปลอดภัย แอดมินแนะนำให้อ่านซีเรียลนัมเบอร์จาก Physical Disk แทน ซึ่งโค้ดในการอ่านก็อยู่ในเว็บบอร์ดแห่งนี้แหละขอรับกระผม
สร้างชุดกุญแจขึ้นมา 1 ชุด
นำ 1 กับ 2 มาทำการเข้ารหัส แน่นอนว่าแอดมินใช้วิธีการเข้ารหัสแบบง่ายๆ ท่านต้องไปศึกษาค้นคว้าเพิ่มเติมเองล่ะกันครับผม
สำหรับชุดโปรแกรมที่ให้ลูกค้า หรือยูสเซอร์ใช้งาน จะต้องทำการอ่านสถานะการลงทะเบียนทุกๆครั้งที่เปิดโปรแกรมขึ้นมา โดยอ่านค่าตัวแรกคือซีเรียลนัมเบอร์ของดิสต์ (ป้องกันการเปลี่ยนแปลงค่าจากผู้ใช้) จากนั้นไปอ่านค่า Product Key หรือรหัสลงทะเบียนที่ได้ทำการ Registry เอาไว้ใน RegEdit หากไม่เจอค่าใดๆ แสดงว่ายังไม่มีการลงทะเบียน ก็ระบุ blnDemo = True หรือยังเป็นชุดทดลองอยู่นั่นเอง แต่หากมีค่า Product Key ก็เอามาทำการเข้ารหัส (เหมือนข้อ 3 ด้านบน) ด้วยซีเรียลนัมเบอร์ฮาร์ดดิสต์กับกุญแจที่กำหนดไว้ แล้วนำมาเปรียบเทียบค่า Product Key ที่ได้ก็เป็นอันจบ ...
การเลือกโปรเจคที่จะให้ทำงานเริ่มต้น (StartUp Project)
http://www.g2gnet.com/webboard/images/vbnet/registerproject.png
การ Registry ค่าต่างๆ การที่แอดมินนำไปไว้ที่ HKEY_CURRENT_USER ก็เพราะว่า Windows 10 มันมีการป้องกันสูง หากนำไปไว้ที่ LOCAL MACHINE มักมีปัญหาในการเขียนค่าลงไป
http://www.g2gnet.com/webboard/images/vbnet/registerregedit.png
มาดูโค้ดในส่วนของการสร้างรหัสลงทะเบียน ... (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 & " "
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 & " "
'// อาจจะมีการเปลี่ยนแปลงค่าใน Registry ก็เลยทำให้ค่าที่ได้ไม่เท่ากัน
Else
blnDemo = True
'// เขียนข้อมูล Volume Disk กลับลงไปใน Registry อีกครั้ง
Call WriteAppRegistry(SectionName, "ProductNumber", ProductNumber)
'// ให้ค่ารหัสลงทะเบียนเป็นค่าว่างเปล่า
Call WriteAppRegistry(SectionName, "ProductKey", "")
Me.Text = Application.ProductName & " "
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 & " "
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 & " "
Me.Close()
Else
'// ลงทะเบียนมั่ว
blnDemo = True
MessageBox.Show("Product Key is not correct.", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
frmCustomerProgram.Text = Application.ProductName & " "
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) ได้ที่นี่ ...
ขอบคุณคะอาจารย์ ร่ำรวยเงินทองและสุขภาพที่ดีนะคะ ขอบคุณครับ อาจารย์ :D:D:Dขอบคุณครับ แก้ไขครั้งสุดท้ายโดย 0x1souce เมื่อ 2022-3-21 16:41
สอบถามหน่อยครับ กรณีที่ใส่ เลขมั่ว 7777777777แบบนี้ หลังจากรันแล้ว project error ครับ ต้องแก้ยังไงคับ
แก้ได้แล้วครับ เปลี่ยนจาก CInt เป็น CLng
แก้ไขครั้งสุดท้ายโดย puklit เมื่อ 2022-10-22 11:42
ก่อนอื่น ผมต้องขอขอบพระคุณอาจารย์เป็นอย่างสูงที่ได้ถ่ายทอดความรู้ให้แบบฟรี ๆ ไม่มีกั๊ก
สำหรับโปรแกรมด้านล่างนี้ผมได้ศึกษาจากอาจารย์แล้วนำมาต่อยอดในการลงทะเบียนดังนี้ครับ
1. คีย์ Product ID
2. คีย์1
3. คีย2
4. จะเป็น Active LicenseKey ที่ผู้ซื้อโปรแกรมจะต้องส่งข้อมูล Product ID , คีย์1 และ คีย2 กลับมาให้ผู้พัฒนา
แล้วทางผู้พัฒนาโปรแกรมก็จะส่ง Active LicenseKey กลับไปให้ผู้ซื้อทำการลงทะเบียนต่อไปครับ
รูปตัวอย่าง การลงทะเบียน Active LicenseKey ที่ถูกต้อง
รูปตัวอย่างการลงทะเบียน Active LicenseKey ไม่ถูกต้อง
สำหรับด้านล้างนี้เป็นข้อมูลที่บันทึกการลงทะเบียนโปรแกรมในระบบ Registry ครับ
กรณียังเป็นเวอร์ชั่นทดลองใช้งาน จะแจ้งเตือนวันคงเหลือ ก่อนเข้าสู่หน้าหลัก
กรณีที่หมดวันทดลองใช้งาน ระบบจะแจ้งเตือน ข้อความหลังเข้าสู่ระบบ และจะไม่สามารถเข้าสู่หน้าหลักของโปรแกรมได้
สำหรับรูปด้านล่างนี้เป็นการถอดรหัสจากคีย์ลูกค้า เพื่อสร้าง License key ส่งกลับไปเพื่อให้ลูกค้าลงทะเบียนครับ
(เวอร์ชั่นล่าสุดผมปรับให้เหลือ 2 คีย์ เท่านั้น)
หน้า:
[1]