# 8. License and demo mode #

← FAQ and troubleshooting · Contents

PBToolboxAI is a commercial library. License checking is entirely offline: no connection, no activation, no server call. A signed key is set at startup and the DLL verifies it locally.

## 8.1 The three key types #

Keys are cumulative: call `PBT_SetLicense` as many times as needed, the library keeps one key per type.

Type | Holder | Unlocks
--- | --- | ---
`dev` | Named, one developer | Only inside the PowerBuilder IDE
`runtime` | Your company, embedded in the application you ship | Only inside a compiled executable
`demo` | Shipped with the demo application | The demo application, inside the IDE, until it expires

A project therefore needs both: one `dev` seat per developer, and one `runtime` key for the application you deliver to your customers.

- A `dev` key that ends up in an executable unlocks nothing.
- A `runtime` key grants no development seat.
- Your end customers have nothing to enter and nothing to activate: the `runtime` key is in your code.

> The "IDE or executable" detection is performed by the DLL itself (process name, design-time modules loaded), not by PowerBuilder code — it cannot be bypassed from your sources.

## 8.2 Setting the key #

Only one thing to do, before the first window opens:

    // Declaration - application object, "Local External Functions"
    Function long PBT_SetLicense (string as_client, string as_key) Library "pbtoolboxai.dll"

    // open event of the application object
    long ll_rc
    string ls_cle_dev

    // The RUNTIME key belongs in the code : it MUST ship inside the exe.
    ll_rc = PBT_SetLicense(gs_titulaire, gs_cle_runtime)

    // The DEV key is read from the workstation : it only unlocks the IDE, and
    // embedded in the code it would ship in every copy without serving anything.
    ls_cle_dev = ProfileString("pbtoolboxai.ini", "license", "dev", "")
    if ls_cle_dev <> "" then ll_rc = PBT_SetLicense(gs_titulaire, ls_cle_dev)

    Open(w_principale)

> The key is set through the DLL function, never through a component method: it applies to the whole process and has to be set before any component exists. That is the same reason `PBT_LicenseStatus` asks for no handle.

The holder is passed in clear, as the first argument: the name (or e-mail address) the licence was issued to, and it must match the one carried by the signed key. A key therefore cannot travel without the name of whoever bought it.

Return | Meaning
--- | ---
`0` | Key valid and retained
`-1` | Invalid key format
`-2` | Invalid signature (key tampered with, or from another vendor)
`-3` | Maintenance expired for this version of the library (see 8.5)
`-4` | `demo` key expired
`-5` | The holder passed does not match the one inside the key

> 💡 Which key goes where. The `runtime` key belongs in the code: it must end up inside the executable you ship. The `dev` key does not — it only unlocks the IDE, so inside an exe it is useless while still travelling around, carrying your company name. Its place is a `pbtoolboxai.ini` file next to the IDE, or a registry value.

Setting the key after a component has been created also works: components that are already open unlock immediately. But the application `open` event remains the simplest place.

> 💡 Keep the key in a constant or in an application resource. It is signed: it contains no exploitable secret and cannot be modified without invalidating its signature.

## 8.3 Checking the license state #

    // Declaration
    Function long PBT_LicenseStatus (ref string as_json, long al_len) Library "pbtoolboxai.dll"

    string ls_statut

    ls_statut = Space(1024)
    PBT_LicenseStatus(ls_statut, 1024)
    // -> {"licensed":true,"ide":false,"keys":{...},"reason":""}

Useful during integration to confirm that a key is taken into account, or to log a startup in your application journal.

## 8.4 Demo mode #

Without a valid key — or with a key that does not apply to the context (a `dev` key inside an exe, for instance) — the library runs in demo mode: everything is usable, everything is visible, but with limits — except the four components of the community edition, described just below, which are never restricted.

### Four components stay free #

The community edition takes no setting up: with no key at all, four components run with no badge and no limit, indefinitely.

Component | What it brings
--- | ---
statictext | Marked-up label: bold, colours, links, bullets, foldable blocks
messagebox | Themed modal dialog with free-form buttons
toaster | Corner-of-screen notifications, with title, image and actions
webbrowser | WebView2 browser hosted inside a PowerBuilder window

The choice is deliberate: these are the four you meet first, they carry no data model of their own, and they are enough to prove on a locked-down machine that the runtime deploys — the real obstacle before any purchase.

The list lives in the DLL. `PBT_LicenseStatus` returns it as it is, under `"free"`: your application can therefore state what it is entitled to without a key, rather than discovering it component by component.

A valid key always wins: on those four components as on any other, it restores your name and your edition.

### The badge #

Every component displays a "PBToolboxAI — DEMO" badge, which cannot be hidden.

### Functional limits #

Component | Limit in demo mode
--- | ---
tab | 3 pages maximum
ribbon | 2 tabs maximum
toolbar | 6 items displayed, across all bars
tilesbox | 8 tiles displayed
All the others | Badge only — no functional limit

These limits apply to the rendering: nothing fails, the display is truncated. So you can genuinely evaluate every component, on your own data, before buying.

Setting a valid key instantly lifts all these limits and removes the badge, without restarting the application.

## 8.5 Perpetual + maintenance #

The license is perpetual: the versions covered by your maintenance period keep working forever, including after that period expires.

In practice, the key carries a maintenance end date, compared against the build date of the DLL:

- a library version released during your maintenance is unlocked permanently;
- a version released after it expires returns `-3`: renew your maintenance to get access;
- applications you have already shipped are never affected: they embed the version they have always used.

## 8.6 Frequently asked questions #

Is my key checked online? No. No network, ever. The check is an RSA signature validated locally by Windows.

Do my customers need a key? No. Your `runtime` key is inside your application; they never see anything about the license.

What happens if I forget `PBT_SetLicense` in production? The application works, but every component displays the demo badge and the limits in the table above apply. That is the first thing to check if a badge shows up at a customer site.

Can I set a `dev` key and a `runtime` key in the same code? Yes — that is even the usual case: the `dev` key applies when you run from the IDE, the `runtime` key when you run the exe. Each one is ignored in the other context.

The badge appears even though the key is set. Three causes, in order of frequency: (1) a `dev` key while you are running a compiled exe, or the other way round; (2) the return value of `PBT_SetLicense` was never tested — check that it is `0`; (3) maintenance expired for the DLL version installed (return `-3`). `PBT_LicenseStatus` settles it in one line.

A key is nominative. A `dev` key is tied to a developer, a `runtime` key to your company. Do not share them outside your team.

← FAQ and troubleshooting · Contents