MS-Access / Getting Started

Licensing Your Applications

For an off-the-shelf application, you may want to license the application in some manner or limit its functionality until someone has registered it with you. Limiting the functionality allows you to create trial versions of your application for distribution.

Even for internal applications with a large rollout, there may be beta testing of an application within an organization. These applications will likely provide the full functionality, but you may want to specify that the beta version is no longer used after a certain period of time.

Creating a Limited-Use Application

A limited-use application is one where you limit what the application can do, typically based on some registration. For a database application, there are a few different ways that you might reduce functionality. First, you might provide an application that provides full functionality but only until a certain date. Second, you might limit the number of records that a user can enter in a given table in the database. If your application is large and contains a number of functional components, a third option is to simply provide a subset of the functionality. Last, you might choose to restrict the number of times an application is launched.

Let's take a look at the different ways to do this in your applications.

Regardless of how you limit functionality, users should know that they're running in a reduced mode.

Expiration Date

The classic mechanism for limiting the use of an application is an expiration date. This practice is still going on today with beta versions of software such as Microsoft Office. Expiration dates have one major issue that you need to watch out for - whether a user can bypass the expiration date mechanism by adjusting the time on their computer. The solution shown here takes this into account.

To prevent users from finding the information easily, we're using the Registry to store information about when the application was used and its expiration date. Start by creating a new standard module and add the following declarations.

' Registry constants
Private Const REG_EXPDATE As String = _
    "HKCU\Software\MyCompany\MyApplication\ExpirationDate"
Private Const REG_LASTUSED As String = _
    "HKCU\Software\MyCompany\MyApplication\LastUsedDate"
Private Const REG_SZ As String = "REG_SZ"
Private Const EXPIRATION_LENGTH_DAYS As Long = 30

Create a routine called SetExpirationDate that sets the expiration date as a value in the Registry. The expiration date is defined by the current date and time plus 30 days.

Private Sub SetExpirationDate()
    ' update the last use date
    Dim objShell As Object
    Dim expDate As Date

    Set objShell = CreateObject("WScript.Shell")

We'll try to read the expiration date from the Registry. If the key does not exist, we'll call the RegWrite method of the WshShell object to write it. The error handling acts as a precaution to ensure that the expiration date is not updated unless the value has not been set.

    On Error Resume Next
    expDate = CDate(objShell.RegRead(REG_EXPDATE))

    If (Err = &H80070002) Then
	' key does not exist, create it
	objShell.RegWrite REG_EXPDATE, Now() + EXPIRATION_LENGTH_DAYS, REG_SZ
    End If

    On Error GoTo 0
    Set objShell = Nothing
End Sub

In addition to storing the expiration date, we'll store the last date that the application was used. This is to prevent the user from tampering with their system clock to work around the expiration date. This routine sets the Registry key defined by the constant REG_LASTUSED to the current date and time.

Private Sub UpdateLastUsedDate()
    Dim objShell As Object
    ' write the key value
    Set objShell = CreateObject("WScript.Shell")
    objShell.RegWrite REG_LASTUSED, Now(), REG_SZ

    Set objShell = Nothing
End Sub

The last function we need will determine whether the application is actually expired. To do this we're going to read both values from the Registry. If either of them doesn't exist, then this is a first boot scenario and we'll call one of the previous routines.
Start by declaring the routine:

Public Function IsExpired() As Boolean
    ' determines whether the expiration date has passed
    Dim expDate As Date
    Dim lastUsed As Date
    Dim objShell As Object

    Set objShell = CreateObject("WScript.Shell")

Next, try to read the expiration date. If this fails, call the SetExpirationDate routine defined earlier.

    ' read the values
    On Error Resume Next
    expDate = objShell.RegRead(REG_EXPDATE)

    ' first use
    If (Err) Then
	SetExpirationDate
	IsExpired = False
	Exit Function
    End If

Try to read the last used date in the Registry. If this fails, call the UpdateLastUsedDate routine defined earlier:

    ' check the last used date
    lastUsed = objShell.RegRead(REG_LASTUSED)
    If (Err) Then
	UpdateLastUsedDate
	IsExpired = False
	Exit Function
    End If
    On Error GoTo 0

We need to add the logic to determine whether the system clock has been tampered with and whether the application is expired. For starters, we know that if the current date and time is before the last used date and time (as stored in the Registry), the system clock has been altered. We'll return True in this case.

    ' if the current system date is less than the last use date then
    ' the user messed with their system clock
    If (Now() < lastUsed) Then
	IsExpired = True
    Else

If this check succeeds, then we need to compare the last used date against the expiration date. If the application is not expired we'll then update the last used date in the Registry.

	' system clock is ok so check the expiration date
	' against the last use date
	IsExpired = (lastUsed >= expDate)

	' update the last usage date
	If (Not IsExpired) Then
	    UpdateLastUsedDate
	End If
    End If
    Set objShell = Nothing
End Function
[Previous] [Contents] [Next]