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:
You'll be including the TurboActivate.dat file in the same folder as the TurboFloat.dll file and you'll use the Version GUID in your code as part of integrating TurboFloat within your app.
Included in TurboFloat Library package is a simple example project. It works with Delphi 7 and newer. The TurboFloatUnit.pas and TurboFloatTypesUnit.pas files contain all the functions you'll be using to add the floating licenses functionality to your app.
Delphi XE (released 2011) and all newer versions are misconfigured. In Delphi, you need to go to "Tools" menu, click "Options", and scroll down to the "Debugger Options -> Embarcadero Debuggers -> Native OS Exceptions" and change 2 settings. First, under the "32-bit Windows OS Exceptions", change the "Privileged Instruction" to be handled by "User program". Next, under the "64-bit Windows OS Exceptions", again, change the "Privileged Instruction" to be handled by "User program":
If you don't do this, then when you run your app under the debugger you'll get exceptions that will crash your app. Why? Because the way TurboActivate works is that it throws exceptions and then catches them internally. However, with Delphi's default value of the "Debugger" handling the "Privileged Instruction", the Delphi debugger interrupts TurboActivate's default behavior with no real benefit other than to annoy and confuse you. This is a poor design choice on Embarcadero's part.
We're going to walk you through adding floating licensing to your app by using our Delphi example application. If you haven't downloaded it already you can get the example app inside the TurboFloat Library package.
Before you can continue, you need to start a TurboFloat Server instance. We recommend spinning-up a TurboFloat Server instance on our infrastructure using LicenseChest. Alternatively, your customers can host the TurboFloat Server on their own infrastructure by activating and installing the TurboFloat Server locally.
We recommend using our hosted TurboFloat Server option because it's fast, stable, up-to-date, and incredibly easy to deploy.
In the example "Text Editor" Delphi application the "frmMain.pas" file is the main UI for the app. That is, it's the entry point for the application. And because it's the entry point of the application it's where we'll be requesting the "license lease" from the TurboFloat Server.
First, create the TurboFloat instance as a private member in the class:
var Form1: TForm1; tf: TurboFloat;
Then, in the constructor for the form, you'll actually create the new instance of the TurboFloat class. Paste the Version GUID you copied from earlier:
procedure TForm1.FormCreate(Sender: TObject); begin Try //TODO: goto the version page at LimeLM and paste this GUID here tf := TurboFloat.Create('PASTE-VERSION-GUID-HERE'); except on Ex : ETurboFloatException do begin ShowMessage('Failed to get a lease from the floating license server: ' + Ex.Message); // Exit the app, and exit the function immediately Application.Terminate; exit; end; end; // ...
Next, we'll actually request the lease from the TurboFloat Server:
Try //TODO: goto the version page at LimeLM and paste this GUID here tf := TurboFloat.Create('PASTE-VERSION-GUID-HERE'); // actually try to request the lease tf.RequestLease(); except
The native TurboFloat library handles all the details about renewing leases, retrying, etc. All you have to do is handle the cases where TurboFloat talks to your app and tells it something has changed (license lease failing to be renewed or new license field data). To do this you need to handle the LeaseChange event. Here we add a new event handler before we request a lease:
Try //TODO: goto the version page at LimeLM and paste this GUID here tf := TurboFloat.Create('PASTE-VERSION-GUID-HERE'); // set the lease changed handler tf.LeaseChange := TurboFloat_LeaseChange; // actually try to request the lease tf.RequestLease(); except
Then, add the "TurboFloat_LeaseChange()" function to handle notifications from the TurboFloat library:
procedure TForm1.TurboFloat_LeaseChange(Sender: TObject; status: LongWord); var frmLeaseExp : TLeaseExpiredFrm; begin if status = TF_CB_FEATURES_CHANGED then begin //TODO: if you're using feature values in your app you might want // to reload them now. ShowMessage('TODO: Reload custom license fields in your app.'); end else begin // TF_CB_EXPIRED, TF_CB_EXPIRED_INET, and everything else // Immediately disable the app and/or show a modal form that // gives the user the option to Save / Save As the data (if // applicable) and let the user re-try connecting to the server. self.Enabled := False; //Note: Don't just close your app. Your users will be rightfully // upset if you do something like that. // Instead, we're showing a modal dialog that lets the user try // to get a new lease from the server. Or, if they can't, then // save their data. frmLeaseExp := TLeaseExpiredFrm.Create(self, tf); if not (frmLeaseExp.ShowModal = mrOk) then begin // Exit the app, and exit the function immediately Application.Terminate; exit; end; // We've gotten a new lease, so re-enable the app. self.Enabled := True; end; end;
Included in the example Delphi app are 3 forms that you might want to copy to your own application:
LeaseExpired.pas: a form to show if the license lease has expired.
InternetErr.pas: a form to show if there's an internet error (that is, a server is specified, but your app couldn't connect to the server).
ServerConfig.pas: a form to allow the end-user to enter details about where their TurboFloat Server is located.
This simple dialog gives your customers easy entry of the details needed to connect to their TurboFloat Server instance, whether they host it on our infrastructure using LicenseChest or they host it locally.
You've already seen example usage of the LeaseExpired form in the TurboFloat_LeaseChange() function. Here's an example usage of the ServerConfig and InternetErr forms. Its logic is fairly simple. First it tries to get a lease, and if that fails then it prompts the user for action:
procedure TForm1.FormCreate(Sender: TObject); var srvConf : TServerConfigFrm; inetErr : TInternetErrFrm; begin Try //TODO: goto the version page at LimeLM and paste this GUID here tf := TurboFloat.Create('PASTE-VERSION-GUID-HERE'); // set the lease changed handler tf.LeaseChange := TurboFloat_LeaseChange; // actually try to request the lease tf.RequestLease(); except on ServEx : EServerException do begin // no server configuration found -- prompt for it srvConf := TServerConfigFrm.Create(self, tf); if not (srvConf.ShowModal = mrOk) then begin ShowMessage('You must specify the location of the floating license server to run YourApp.'); // Exit the app, and exit the function immediately Application.Terminate; exit; end; end; on Ex : ETurboFloatException do begin // Give the user an option to try another server if they // couldn't connect to the first one, or if the first one // is for a different product, of if the username is not // allowed to request leases from that particular server. if (Ex is EInternetException) Or (Ex is EWrongServerProductException) Or (Ex is EServerUUIDMismatchException) Or (Ex is EUsernameNotAllowedException) Then begin inetErr := TInternetErrFrm.Create(self, tf); if not (inetErr.ShowModal = mrOk) then begin // exit the app on failure Application.Terminate; exit; end; end else begin ShowMessage('Failed to get a lease from the floating license server: ' + Ex.Message); // Exit the app, and exit the function immediately Application.Terminate; exit; end; end; end; end;
After you've successfully requested a lease from the TurboFloat Server, the TurboFloat library integrated in your app takes care of renewing the leases automatically and silently. You'll only ever get a notification of something going wrong in the handler for the LeaseChange event that we covered in Step 3.
When your app is closing you should "drop" the lease using the
DropLease() method, and cleanup the memory using the
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Try // Drop the lease if tf.HasLease() Then begin tf.DropLease(); end; // Cleanup the memory used by the TurboFloat library TurboFloat.Cleanup(); except on Ex : ETurboFloatException do begin // we're exiting anyway, just let the lease be a zombie. end; end; end;
What this does is tell the TurboFloat Server that you're through using the lease in this instance of your app, and another instance of your app on another computer or another session can now use that "free slot".
If you can't drop the lease (because your app can't connect to the internet, or for any other reason), and you choose to exit your app anyway, then the "lease" on the TurboFloat Server will be a "zombie". The lease will expire eventually on the TurboFloat Server, and thus the free slot will open back up.
Testing requesting leases, dropping them, and everything else in the TurboFloat Library is intuitive: just call the function and it does the thing you want it to do. Testing the lease change event is, however, slightly less intuitive. Here's how you can test the lease change event:
If your app is open and has a lease, close your app and make sure it drops the license lease from the TurboFloat Server.
Stop the TurboFloat Server instance.
Save the changes you made to the configuration file.
Start your TurboFloat Server instance again.
Start your app again, and make sure it successfully gets a license lease from the TurboFloat Server.
Now, stop the TurboFloat Server instance, but leave your app running.
Within the next 30 seconds the lease change event will be called because the TurboFloat Library was not able to renew the license lease automatically.