|
สำหรับบทความนี้จะเป็นวิธีการง่ายๆในการทำชุดลงทะเบียนโปรแกรม ซึ่งแอดมินได้สร้างโปรเจค 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
|