LimeLM
wyBuild
Support forum
wyDay blog
wyDay Home

Using TurboActivate with Xojo (Real Studio / Real Basic)

XojoThis article will give step-by-step instructions on how to add software licensing (specifically, hardware-locked or node-locked licensing) to your Xojo app. 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.

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, macOS (Mac OS X), or Linux. It contains the native library and source code examples needed to integrate hardware-locked licensing in your Xojo app:

Step-by-step walkthrough: adding licensing and trials to your Xojo app

Now we're going to walk you through each step you need to take in adding licensing, online activation, and timed-trials to your Xojo 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 and it requires more work on your end. 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, inside the extracted folder you'll find 2 folders: the "API" directory and the "bin-*" directory (for example, bin-windows, for the Windows TurboActivate package).

Step 2. 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 3. Download TurboActivate.dat

Go to your version page in LimeLM. Download the "TurboActivate.dat" file, and make a note of the Version GUID you see on your product version page (you'll be using it in the next step).

TurboActivate.dat and Version GUID

You'll be copying this TurboActivate.dat files in the next step to sit alongside your executable files in each of the platforms you want to support.

Side-note about TurboActivate.dat file: this file is an "information file" about your product version, and gives TurboActivate enough information to verify product keys and cryptographically signed activation data locally. It's a read-only file (license data will never be written to it).

Step 4. Add TurboActivate to your project

Included in TurboActivate API packs (get them on the API page) is a simple Xojo (Real Basic) example project. We've also included all the files you need to add to your Xojo project within the "Import to your project" folder. Just drag all of the files in that folder into your Xojo "Project" tab (or add the files one-by-one using the "File -> Import..." menu). The TurboActivate module contains all the functions you'll be using to add licensing, online-activation, and trial functionality to your app.

TurboActivate on Windows

On Windows you'll be using the x86 version of TurboActivate. Copy the TurboActivate.dll to the same folder as the example project (and your project). And while you're at it put the TurboActivate.dat file that you downloaded earlier in this same folder. Now you can use TurboActivate while debugging your app. If you're not outputting your final exe to the same folder as your Xojo project then make sure to include the TurboActivate.dll and TurboActivate.dat files in the same folder as your outputted *.exe file.

TurboActivate on macOS

macOS is a bit different than Windows. On Windows, when you build your app, you have a single exe and all you have to do is include the TurboActivate.dat and TurboActivate.dll files in the same folder as that exe. On macOS, however, when you build your app a "bundle" is created. If you're not familiar with macOS an "app bundle" is like an exe (you double click it and your app runs), however behind the scenes the "bundle" is just a folder with the actual app and resources in sub-folders.

For instance, when you use our example Xojo project and build on Mac a "TestApp" bundle will be output:

RealBasic app bundle

This is really a folder called "TestApp.app". When you're releasing your app for customers you'll want the TurboActivate.dat and libTurboActivate.dylib files to be inside the app bundle. You can do this manually by right clicking the app bundle (in the example, TestApp) then clicking "Show Package Contents":

Open the app bundle

Add the TurboActivate.dat file to the TestApp.app/Contents/MacOS/ folder and add the libTurboActivate.dylib file to the TestApp.app/Contents/Frameworks/ folder.

If you actually want to use TurboActivate while you're debugging your app then you need to make a temporary change to the "TALibrary" constant in the TurboActivate module:

Specify the TA library

For instance, to use the libTurboActivate.dylib in the same folder as your app's bundle, then change the "Mac OS" value to the following:

@executable_path/../../../libTurboActivate.dylib

You'll also need to call PDetsFromPath() to load the TurboActivate.dat. For example, put this before you make any TurboActivate function calls:

#If DebugBuild
    ta = new TurboActivate("Paste GUID Here", "/location/to/TurboActivate.dat")
#else
    ta = new TurboActivate("Paste GUID Here")
#Endif

A good place to put these lines of code is before your call to IsGenuine() or IsActivated().

Step 5. 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 create the "TurboActivate" object with your version GUID like so:

' TODO: goto the version page at LimeLM and paste this GUID here
ta = new TurboActivate("Paste GUID Here")

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

Step 6. 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.

The the example we're creating a simple variable "isGenuine" to save whether the customer is activated and genuine. And then it's simply a matter of making a call to IsGenuine(X, Y, Z) 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:

Try
  'TODO: goto the version page at LimeLM and paste this GUID here
  #If DebugBuild
    ta = new TurboActivate("Paste GUID Here", "/location/to/TurboActivate.dat")
  #else
    ta = new TurboActivate("Paste GUID Here")
  #Endif

  ' 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/
  Dim gr As IsGenuineResult = ta.IsGenuine(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 new ReVerifyNow(ta, DaysBetweenChecks, GracePeriodLength)
    frmReverify.ShowModal()

    If frmReverify.OKClicked Then
      isGenuine = True
    ElseIf Not frmReverify.noLongerActivated Then
      ' the user clicked cancel and the user is still activated
      ' Just bail out of your app
      Quit
      Exit Sub
    End If
  End If


Catch err As TurboActivateException
  MsgBox "Failed to check if activated: " + err.Message

  ' End your application immediately
  Quit
End Try

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 IsGenuine(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 prompt them to do that (also included in the example project).

Step 7. 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 ("PKey") 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. Now we need to handle when the user clicks the Activate/Deactivate menu that you created. You can add code to Deactivate if the user is activated, or launch the "PKey" form if the user isn't activated:

Try

  If isGenuine Then
    ' deactivate product without deleting the product key
    ' allows the user to easily reactivate
    ta.Deactivate(False)
    isGenuine = False
    ShowTrial(True)
  Else
    ' use a simple activation interface
    Dim pkeyDialog as new PKey(ta)
    pkeyDialog.ShowModal()

    ' recheck if activated
    isGenuine = ta.IsActivated()

    If isGenuine Then
      ReEnableAppFeatures()
      ShowTrial(False)
    End If
  End If

Catch err As TurboActivateException
  MsgBox "Failed to activate: " + err.Message
  Return False
End Try

Return True

A note about TA_USER vs. TA_SYSTEM

In the included example app, the PKey window calls ta.CheckAndSavePKey(txtPKey.Text, TA_SYSTEM) when the "Activate" button is clicked. The TA_SYSTEM flag tells TurboActivate to store the activation data to directories where all users on that machine would have the ability to read/write the activation data. If you were using TA_USER instead, this would tell TurboActivate to store the activation data in directories that the user has the ability to write to.

In both cases the activation data locks to the machine. The only difference is where the activation data is stored. We typically recommend using TA_SYSTEM, however the only downside to using that flag is that the first time (and only the first time) you call a function with the TA_SYSTEM flag your app needs "elevated" or "sudo" permission.

Step 8. Adding trial functionality

In this example we're going to use verified trials because they are accurate, fast, and allows you to track conversion of customers. Starting the verified trial and seeing how many days are remaining is as simple as this:

' 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	


lblTrialMessage.Visible = show
btnExtendTrial.Visible = show

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

  Dim trialDaysRemain As Integer = 0

  Try
    ta.UseTrial(trialFlags)

    ' get the number of remaining trial days
    trialDaysRemain = ta.TrialDaysRemaining(trialFlags)
  Catch tee As TrialExpiredException
    ' do nothing because trialDaysRemaining is already set to 0
  Catch ex As TurboActivateException
    MsgBox "Failed to start the trial: " + ex.Message
  End Try


  ' if no more trial days then disable all app features
  If trialDaysRemain = 0 Then
    DisableAppFeatures()
  Else
    lblTrialMessage.Text = "Your trial expires in " + Str(trialDaysRemain) + " days."
  End If
Else
  mnuActDeact.Text = "Deactivate"
End If