LimeLM
wyBuild
Support forum
wyDay blog
wyDay Home

Using TurboActivate with Visual Basic for Applications (VBA)

VBAThis article will give step-by-step instructions on how to add software licensing (specifically, hardware-locked or node-locked licensing) to your VBA app or extension. There's also a full example app that you can download and play with without needing to add licensing to your app.

By the end of this article you'll have working licensing integrated with your application, and thus the ability to sell individual copies of your software.

This article shows you how to add hardware-locked licensing to your VBA app (using TurboActivate). To add floating-licensing to your VBA app see the "Using TurboFloat with VBA" article.

Sign up or login and download the native TurboActivate library

Before you can do anything, you need to login to your LimeLM account (or sign up). Then download TurboActivate for Windows or macOS. It contains the native library and source code examples needed to integrate hardware-locked licensing in your VBA app:

Adding licensing & online activation to your appTurboActivate.dat and Version GUID

After you've created a new product, go to the version page of the product you will be adding licensing to. You will need to do 2 things:

  1. Download the TurboActivate.dat file for the product version.

  2. Make a note of the Version GUID.

You'll be including the TurboActivate.dat file in the same folder as the TurboActivate.dll or libTurboActivate.dylib files. You'll use the Version GUID in your code as part of integrating TurboActivate within your app.

Example project

Included in both the TurboActivate.zip and TurboActivate-Mac.zip packages is a simple VBA example project. The TurboActivate.cls and TurboActivateHelper.bas files in the "API\VBA" folder contains all the functions you'll be using to add licensing, online-activation, and trial functionality to your app.

Step-by-step walkthrough

Now we're going to walk you through each step you need to take in adding licensing, online activation, and timed-trials to your VBA app. There are lots of ways you can add licensing to your app, but there are 2 popular styles:

  1. Separate versions of your app. This style of licensing is where you build 2 versions of your product: a trial version and a full version.

  2. Hybrid version of your app. This style of licensing is where your product is the trial version or the full version depending on whether the user is activated.

The first method (the separate versions method) is possible with TurboActivate, but we're not going to talk about it here because it's not very user friendly. Instead we'll talk about making your app a hybrid Full/Trial app. That is, your users will be able to use your app in "trial mode" until either the trial expires or they purchase a product key and use it to activate your app.

Step 1. Signup for LimeLM, download TurboActivate

If you haven't already signed up for LimeLM then sign up now. All plans have a 30-day free trial. Or, if you're just putting your toes in the water, there's even a free plan that has no time limit and doesn't require a credit card.

After you've created your account, download TurboActivate and extract it anywhere. After you extract it you'll find 4 folders:

Step 2. Add TurboActivate to your project

Now you need to add TurboActivate to your app. Add "TurboActivateHelper.bas" and "TurboActivate.cls" files from the "VBA" project you extracted from the TurboActivate main package. You do this by right clicking your project in Visual Basic and clicking "Import File..." and browsing for the "TurboActivateHelper.bas" and "TurboActivate.cls" files:

Adding existing files to VBA

Step 3. Special instructions for Windows

Step 3a. Use STDCALL files

If your VBA app will be running on Windows then you'll need to use the "stdcall" version of TurboActivate (in the "stdcall" folder in the "TurboActivate Library package").

Also, if you're targeting the 64-bit version of Windows (e.g. you're app is an extension that will run in 64-bit version of Microsoft Office) then you'll need to include the x64 version of TurboActivate (from the "stdcall\x64" folder), but rename it to "TurboActivate.x64.dll". This way you can include both the x86 and x64 versions of TurboActivate and target both versions of Office without having to release 2 separate versions of your app.

Step 3b. Set the file locations

Next, you'll need to tell TurboActivate where to find the TurboActivate.dll, TurboActivate.x64.dll, and TurboActivate.dat files. For Windows we recommend keeping these files all in the same folder and then opening the "TurboActivateHelper.bas" and modifying the GetTADirectory() to return the path where these files will be found. By default, on Windows, GetTADirectory() returns "ThisWorkbook.path", which is the location of the *.xlam file.

Step 4. Special instructions for Mac OS X

The Mac OS X versions of Microsoft Office can't load the libTurboActivate.dylib from arbitrary locations. This means you'll need to make an installer for your add-in, and that installer will install the VBA extension somewhere and also install the "libTurboActivate.dylib" and "TurboActivate.dat" files to a pre-defined location. You'll then be able to hard-code these predefined locations inside your app.

Step 4a. Hardcode location of libTurboActivate.dylib

To hardcode the location of the libTurboActivate.dylib file, modify the TurboActivate.cls file with the path you'll be using in your installer:

#If Mac Then
Private Declare Function TA_GetHandle Lib "/Library/Application Support/Microsoft/YourApp/libTurboActivate.dylib" (ByVal VersionGUID As String) As Long
...

Apply that same hardcoded location to all the "Private Declare Function" statements in the Mac section of the #If block.

Step 4b. Hardcode location of TurboActivate.dat

Next, you'll need to tell TurboActivate where to find the TurboActivate.dat file. Open the "TurboActivateHelper.bas" and modify the GetTADirectory() to return the path where the TurboActivate.dat file will be found.

Office 2016 (and newer) for Mac OS X have a new "sandboxing" feature. What this means is that on Mac OS X, you need to put the "libTurboActivate.dylib" and "TurboActivate.dat" files in a location that Office 2016 can grant permission to use its sandbox. One good location to put those files would be here: /Library/Application Support/Microsoft/YourApp/, and replacing "YourApp" with your application name.

Then, at the start of your application, you need to grant permission for the files that TurboActivate will use. So, in the example "YourVBAProject.xlam", the "Workbook_Open" function looks like this:

Private Sub Workbook_Open()

    Dim pdetsFilename As String
    pdetsFilename = GetTADirectory() & Application.PathSeparator & "TurboActivate.dat"

    'Note: Did you open the TurboActivateHelper.bas module and change the GetTADirectory() function
    ' to return the correct path to your TurboActivate.dat file? If not, you'll almost certainly
    ' get an error.

    #If Mac And MAC_OFFICE_VERSION >= 15 Then
        Dim fileAccessGranted As Boolean
        Dim filePermissionCandidates

        'Create an array with file paths for which permissions are needed
        filePermissionCandidates = Array("/Library/Application Support/Microsoft/YourApp/libTurboActivate.dylib", pdetsFilename)

        'Request access from user
        fileAccessGranted = GrantAccessToMultipleFiles(filePermissionCandidates)

        ' show an error message to the user and exit immediately
        If Not fileAccessGranted Then
            MsgBox "Failed get access to necessary files."
            ExitAppNow
            Exit Sub
        End If
    #End If

    'TODO: Create the TurboActivate instance, and if it fails, exit the addin immediately

End Sub

Step 5. Create a new product in LimeLM

If you haven't already created a new product in LimeLM, do it now. You can change any value later, so don't worry about making a mistake.

Adding your first product to LimeLM

Step 6. Download TurboActivate.datTurboActivate.dat and Version GUID

Go to your version page in LimeLM. Download the "TurboActivate.dat" file. Now copy this file to the same folder(s) you added TurboActivate.dll and TurboActivate.exe to in step 3.

Step 7. Creating the TurboActivate instance

Now, inside your app, you need to create a new TurboActivate object with the Version GUID found on the same page you downloaded the TurboActivate.dat from. In the example app we define the "ta" variable in the "main form" class, and then create the TurboActivate object in the form's constructor:

Public ta As TurboActivate

Private Sub Form_Load()

    ' create the new TurboFloat instance
    Set ta = New TurboActivate

    ' tell your app to handle errors in the section
    ' at the end of the sub
    On Error GoTo TAProcError

    'TODO: goto the version page at LimeLM and paste this GUID here
    Call ta.Init("Paste GUID Here")

    ' ...

Replace the "Paste GUID Here" string with the Version GUID string your copied from your version page.

Step 8. Checking if the customer is genuinely activated

There are many ways you can use TurboActivate to add licensing to your application. For this example we're going to keep it simple.

Scroll up to your form constructor code and add a "Boolean" "isGenuine" variable to save whether the customer is activated and genuine. And then it's simply a matter of making a call to IsGenuine() to see if the user is activated and to re-verify the activation with the LimeLM servers every 90 days, with a 14 day grace period:

Public ta As TurboActivate

' store the isGenuine result
Dim IsGenuine As Boolean

Dim DaysBetweenChecks As Long
Dim GracePeriodLength As Long


Private Sub Form_Load()

    ' Don't use 0 for either of these values.
    ' We recommend 90, 14. But if you want to lower the values
    ' we don't recommend going below 7 days for each value.
    ' Anything lower and you're just punishing legit users.
    DaysBetweenChecks = 90
    GracePeriodLength = 14


    ' create the new TurboFloat instance
    Set ta = New TurboActivate

    ' tell your app to handle errors in the section
    ' at the end of the sub
    On Error GoTo TAProcError

    'TODO: goto the version page at LimeLM and paste this GUID here
    Call ta.Init("Paste GUID Here")

    Dim gr As IsGenuineResult

    ' Check if we're activated, and every 90 days verify it with the activation servers
    ' In this example we won't show an error if the activation was done offline
    ' (see the 3rd parameter of the IsGenuine() function)
    ' https://wyday.com/limelm/help/offline-activation/
    gr = ta.IsGenuineEx(DaysBetweenChecks, GracePeriodLength, True)

    IsGenuine = gr = IsGenuineResult.Genuine Or _
                gr = IsGenuineResult.GenuineFeaturesChanged Or _
                gr = IsGenuineResult.InternetError


    ' If IsGenuineEx() is telling us we're not activated
    ' but the IsActivated() function is telling us that the activation
    ' data on the computer is valid (i.e. the crypto-signed-fingerprint matches the computer)
    ' then that means that the customer has passed the grace period and they must re-verify
    ' with the servers to continue to use your app.

    'Note: DO NOT allow the customer to just continue to use your app indefinitely with absolutely
    '      no reverification with the servers. If you want to do that then don't use IsGenuine() or
    '      IsGenuineEx() at all -- just use IsActivated().
    If Not IsGenuine And ta.IsActivated Then
        ' We're treating the customer as is if they aren't activated, so they can't use your app.

        ' However, we show them a dialog where they can reverify with the servers immediately.

        Dim frmReverify As ReVerifyNow
        Set frmReverify = New ReVerifyNow

        If frmReverify.ShowDialog(ta, DaysBetweenChecks, GracePeriodLength) = vbOK Then
            IsGenuine = True
        ElseIf Not frmReverify.noLongerActivated Then ' the user clicked cancel and the user is still activated
            ' Just bail out of your app
            End
            Exit Sub
        End If
    End If


    ' Show a trial if we're not genuine
    ' See step 10, below.
    ShowTrial (Not IsGenuine)

ProcExit:
    Exit Sub

TAProcError:
    MsgBox "Failed to check if activated: " & Err.Description

    ' End your application immediately
    End
End Sub

This is a complete example showing how to check if the customer is genuinely activated, and how to handle the error cases. While it's longer than "toy" licensing solutions, it's built for the real world.

The code does the following:

  1. It creates the new TurboActivate instance with your Version GUID.

  2. Checks if the customer is activated and re-verifies with the servers every 90 days (with a 14-day grace period).

  3. And if IsGenuineEx(x, y, z) tells you the customer is not genuine then you can use IsActivated() to determine if they're "not genuine" because they were never activated or if it's because the customer has gone more than DaysBetweenChecks + GracePeriodLength days since re-verifying with the activation servers.

  4. And if it's a case where the customer must re-verify with the activation servers, then show a form that lets them do that (also included in the example project).

Step 9. Prompting for the user's product key

If the user has never activated, or if they've since deactivated, then you'll need to prompt the user to enter their product key. You can do this a couple of ways, in this example we'll just use a simple form ("frmPKey") to prompt the customer to enter their product key.

The first thing you need to do is a new Activate/Deactivate menu to your form. You can name it anything you want — in this example we call it mnuActDeact:

Add Activate/Deactivate menu to your app

After you've created a menu, a button, or some other UI element for the customer to activate and deactivate, create the event handler for that UI element. In this example the event handler is "mnuActDeact_Click" function. You can add code to Deactivate if the user is activated, or launch "frmPKey" form if the user isn't activated:

Private Sub mnuActDeact_Click()
    If IsGenuine Then
        ' tell your app to handle errors in the section
        ' at the end of the sub
        On Error GoTo TAProcError


        'deactivate product without deleting the product key
        'allows the user to easily reactivate
        ta.Deactivate
        IsGenuine = False
        Call ShowTrial(True)
    Else
        ' tell your app to handle errors in the section
        ' at the end of the sub
        On Error GoTo TAProcIsActError

        ' launch the product key form
        Dim pkeyBox As frmPKey
        Set pkeyBox = New frmPKey

        Dim diagResult As VbMsgBoxResult
        diagResult = pkeyBox.ShowDialog(ta)

        If diagResult = vbOK And ta.IsActivated Then
            IsGenuine = True
            ReEnableAppFeatures
            Call ShowTrial(False)
        End If
    End If

ProcExit:
    Exit Sub

TAProcError:
    MsgBox "Failed to deactivate: " & Err.Description
    Resume ProcExit

TAProcIsActError:
    MsgBox "Failed to check if activated: " & Err.Description
    Resume ProcExit
End Sub

Step 10. Adding trial functionality

In other parts of this example you've seen references to a ShowTrial() function. This is a function that you'll need to create to add trial functionality to your app. In this example we're going to use verified trials (because they are accurate, fast, and allows you to track conversion of customers).

The first step is to actually tell TurboActivate you'll be using verified trials. Create a trialFlags at the top of your main form that will store this information:

Public ta As TurboActivate

' store the isGenuine result
Dim IsGenuine As Boolean

Dim trialFlags As Long

Dim DaysBetweenChecks As Long
Dim GracePeriodLength As Long


Private Sub Form_Load()

    ' Set the trial flags you want to use. Here we've selected that the
    ' trial data should be stored system-wide (TA_SYSTEM) and that we should
    ' use un-resetable verified trials (TA_VERIFIED_TRIAL).
    trialFlags = TA_SYSTEM Or TA_VERIFIED_TRIAL

    ' Don't use 0 for either of these values.
    ' We recommend 90, 14. But if you want to lower the values
    ' we don't recommend going below 7 days for each value.
    ' Anything lower and you're just punishing legit users.
    DaysBetweenChecks = 90
    GracePeriodLength = 14



    ' ...
End Sub

Now we have to make a few functions:

  1. ShowTrial(bool show)

  2. DisableAppFeatures()

  3. ReEnableAppFeatures()

In the ShowTrial method you can show how many trial days remain for the user. You can open the VBA example from TurboActivate.zip if you want to see a full example. Here we'll set the activate menu text to either "Activate" or "Deactivate" and will disable the app features if there are no more trial days remaining:

Private Sub ShowTrial(ByVal show As Boolean)
    lblTrialMessage.Visible = show
    btnExtendTrial.Visible = show

    If show Then
        mnuActDeact.Caption = "Activate..."

        Dim TrialDaysRemaining As Long
        TrialDaysRemaining = 0

        ' ignore errors for the following 2 functions
        On Error Resume Next

        Call ta.UseTrial(trialFlags)

        ' get the number of remaining trial days
        TrialDaysRemaining = ta.TrialDaysRemaining(trialFlags)

        ' re-enable error handling
        On Error GoTo 0

        ' if no more trial days then disable all app features
        If TrialDaysRemaining = 0 Then
            DisableAppFeatures
        Else
            lblTrialMessage.Caption = "Your trial expires in " & TrialDaysRemaining & " days."
        End If
    Else
        mnuActDeact.Caption = "Deactivate"
    End If
End Sub

Now you can add the functions to your code to disable and enable your application features:

Private Sub DisableAppFeatures()
    'TODO: disable all the features of the program
End Sub

Private Sub ReEnableAppFeatures()
    'TODO: re-enable all the features of the program
End Sub

In the example VBA project the app "feature" we enable/disable is the text box. Obviously you need to tailor this to your specific application.

Now that we have the foundation set we can actually start calling these functions. Scroll back up to the form's constructor and add the call to the ShowTrial() function:

Private Sub Form_Load()

    ' ...

    ' create the new TurboFloat instance
    Set ta = New TurboActivate

    ' tell your app to handle errors in the section
    ' at the end of the sub
    On Error GoTo TAProcError

    'TODO: goto the version page at LimeLM and paste this GUID here
    Call ta.Init("Paste GUID Here")

    ' ...

    ShowTrial (Not IsGenuine)

ProcExit:
    Exit Sub

TAProcError:
    ' Handle exception
End Sub