Introduction
Access to most applications is controlled by a software licensing system. These systems usually require the user to enter the license key into the application so it can be stored and referenced by the application to ensure legitimate use of the software.
I have had a number of user requests regarding the best way to do this in a user friendly manner. I thought I would share some of the techniques I have seen and used in the past based on my experience with Serial Key Maker.
The attached sample solution project contains a VB.NET and C# (both 2008) implementation of the techniques I will discuss.
Download and unzip the sample code, and follow along.
The techniques I cover in this application are:
- Creating the data entry form for capturing the license key
- Encrypting the key and storing it in the Registry
- Reading the key from the Registry and decrypting it
- Providing immediate feedback to the user regarding the status of the license key
- Using a single text box, or having the key split across multiple text boxes
- Automatically detecting when a user has copied a license key, and automatically validating and storing it without their input needed
Capturing the License Key
For simplicity, I do not use a real licensing system for this project. I have hard coded the key validation to expect a 20 character string value for a full version key, and 20 digit number for a demo license key. In reality, you would use a system like Serial Key Maker to create and validate the actual license key.
The project consists of a start up form (frmMain
) and a license entry form (frmCaptureLicenseKey
). When the project starts, it loads frmMain
. Clicking on the 'Add License' form opens a license entry form.
When you type in a character into the text box, the application calls "CheckValid
" with the contents of "txtRegister.Text
". "CheckValid
", in turn, uses the WorkObject
class to check for a valid key object. "ValidateKey
" is where you would normally plug in the logic of your licensing validation system like the Serial Key Maker API. For now, I just crudely expect a 20 character string, or a 20 digit number.
objKey = WorkObject.ValidateKey(p_strUnencryptedKey)
If Not objKey Is Nothing AndAlso objKey.IsValid Then
blnIsValid = True
btnSave.Enabled = True
If objKey.Expires Then
lblRegStatus.ForeColor = Color.Blue
lblRegStatus.Text = "Demo Copy"
lblExpires.ForeColor = Color.Blue
lblExpires.Text = "Expires: " & objKey.DateValidThrough.ToShortDateString
Else
lblRegStatus.ForeColor = Color.Green
lblRegStatus.Text = "Registered Copy."
lblExpires.ForeColor = Color.Green
lblExpires.Text = String.Empty
End If
Else
btnSave.Enabled = False
lblRegStatus.ForeColor = Color.Red
lblRegStatus.Text = "Key Not Valid."
lblExpires.ForeColor = Color.Red
lblExpires.Text = "Expired."
End If
The KeyDetails
class is an object to hold the properties of the license key, and has the following properties:
Expires
IsValid
DateValidThrough
DateCreated
You can extend the display of the demo version text to include how many days more the user has in the demo version, using the DateDiff
function on the "DateValidThrough
" and "DateCreated
" fields of the KeyDetails
object that is returned (not implemented in this sample).
Notice: "CheckValid
" is called whenever a character changes or the timer event fires. This provides the user with instant feedback regarding the status of their license key input. They do not need an additional step to see if what they have is valid.
Split Text Boxes
Some users prefer to have the long license key split into multiple text boxes to make reading easier. I have included logic in this sample to do just that. You can hide the full textbox at form load and display the 4 split text boxes, or let the user choose which format they want the license key to be in.
One thing that greatly annoys me about the split textbox method is that it makes it very difficult to paste a license key into the boxes. The user has to do it piece by piece. I solve this problem by implementing a routine that splits whatever is pasted into a text box into the remaining text boxes, using the "txtSplit_TextChanged
" method. If a user pastes 20 characters into the first split textbox, the method will place 5 characters into each of the 4 textboxes using this logic:
If txtSplit1.Text.Length > 5 Then
strText = WorkObject.StripHyphens(txtSplit1.Text)
txtSplit1.Text = strText.Substring(0, 5)
txtSplit2.Text = strText.Substring(5)
End If
and so on.
Another variation you could employ is to hide the split textboxes when they get focus and show the full text box. Then, when the full text box loses focus, you can hide it and show the split text box, making reading easy once again.
Encrypting the Key and Saving it
When the user elects to save the license key, this application saves it to the Registry in the "SaveLicenseKeyToReg
" method. It first encrypts the key using the WorkObject
's "EncryptMD5
" method, which uses the Framework's "Security.Cryptography
" library.
Try
strEncryptedKey = EncryptMD5(p_strLicenseKey, m_strLocalPassword)
SaveSetting(Reg_Folder, Reg_Section, cstr_LICENSE_KEY, strEncryptedKey)
blnReturn = True
Catch ex As Exception
blnReturn = False
End Try
Reading the Key and Decrypting it
You would then do the reverse when you need to read the key (on application startup, for example). The "GetLicenseKeyFromRegistry
" method of the WorkObject
, for example, reads the encrypted key we stored from the Registry and then runs it through our decryption routine.
strEncryptedKey = GetSetting(Reg_Folder, Reg_Section, cstr_LICENSE_KEY, String.Empty)
If Not String.IsNullOrEmpty(strEncryptedKey) Then
strLicenseKey = DecryptMD5(strEncryptedKey, m_strLocalPassword)
End If
Monitoring the Clipboard
A neat trick to help your users is to monitor the clipboard for the presence of your license key. If you detect a license key that fits your format, you can then register the product for them without needing them to do anything. This should have a profound effect on them in terms of how they perceive your level of concern for them!
So, when a user receives a license key via email from you, and they copies it to paste it into your application, you can do all the dirty work for them.
This sample does exactly that. There is a timer running on the main form which checks the Registry every second. If it finds a key on the clipboard using:
strClipboardText = Clipboard.GetText(TextDataFormat.Text);
it validates it as either a full or demo version of the key. Then, you can go ahead and store it for the user, and let them know that nothing else is required of them, and you can go ahead and unlock your application.
Note: Be sure to turn the timer off if the key validates so that it stops checking. You will also want to disable this functionality if the key stored in the Registry is the same as the one on the clipboard (not implemented in this sample) so that it stops notifying them of the key in future runs of the application.
Conclusion
With a little care, you can take the pain out of managing license keys for your users by paying attention to the details of what they would need to do. I believe the trick of automatically validating and saving the license key when your application detects it on the clipboard will impress your users, and is well worth the effort.
Thank you for downloading and reading.
Puresoto Group, Inc, and Puresoto Group Consulting provides custom software development solutions. While we specialize in Healthcare solutions, we provide expert consulting on a wide range of Windows based technologies, including data manipulation, productivity enhancements through tools and applications and custom web development.