Querying the OEM application license in a PLC application
![]() | If you use OEM licenses make sure you encrypt your boot project! Remember that the license ID queried via FB_CheckLicense in the binary code can easily be found and (with a little effort) manipulated with a hex editor. Therefore, be sure to encrypt your boot project (safest), or at least disguise the queried license ID in the source code as best as possible. |
The license check in the TwinCAT Runtime startup process takes place in two steps:
- 1. TwinCAT 3 first reads the license files stored in the system (on the hard disk), checks their contents and creates an internal list of the licenses found.
- 2. The final check of the licenses takes place after commissioning of the EtherCAT bus, because only then all necessary information is available. (Before this, the presence of an EL6070 license terminal, for example, cannot be verified)
You can retrieve the result after the completed startup with the function block FB_CheckLicense.
During operation (after startup and final license check) the status of the licenses is checked again by the TwinCAT Runtime approx. every two minutes. This should be taken into account accordingly in the PLC program (e.g. call FB_CheckLicense only every 10 seconds).
Notes:
- FB_CheckLicense only reads the currently stored license status in the internal table, but does not trigger a new license check. Removing a dongle while the system is running can therefore take up to two minutes before the license status of the associated license becomes noticeable.
- Tip: if required, dongles currently connected to the system can be determined using the function block FB_GetLicenseDongles.
- The license check is part of the TwinCAT Runtime startup process. Means: no running runtime = no current license information!
FB_CheckLicense
The function block determines the TwinCAT 3 license status for a given license ID.
VAR_INPUT
VAR_INPUT
bExecute : BOOL;
tTimeout : TIME;
sNetId : T_AmsNetId;
stLicenseId : GUID;
END_VAR
bExecute: The function block is activated by a positive edge at this input.
tTimeout: Timeout time that must not be exceeded when the command is executed.
sNetId: AmsNetId (AMS network identifier) of the TwinCAT computer whose license status is to be read (type: T_AmsNetId). If it is to be run on the local computer, an empty string can be entered.
stLicenseId: License ID (type: GUID)
VAR_OUTPUT
VAR_OUTPUT
bBusy : BOOL;
bError : BOOL;
nErrorId : UDINT;
stCheckLicense : ST_CheckLicense
END_VAR
bBusy: TRUE, as long as the function block is active.
bError: TRUE if an error occurs during command execution.
nErrorId: Supplies the ADS error number when the bError output is set.
stCheckLicense: Structure with license data (type: ST_CheckLicense)
STRUCT ST_CheckLicense
TYPE ST_CheckLicense :
STRUCT
stLicenseId : GUID;
tExpirationTime : TIMESTRUCT;
sExpirationTime : STRING(80);
eResult : E_LicenseHResult;
nCount : UDINT;
END_STRUCT
END_TYPE
Name | Description |
---|---|
stLicenseId | License ID |
tExpirationTime | Expiry date |
sExpirationTime | Expiry date |
eResult | License status (see E_LicenseHResult) |
nCount | Number of instances for this license (0=unlimited) |
ENUM E_LicenseHResult
TYPE E_LicenseHResult :
(
//success
E_LHR_LicenseOK : DINT := 0,
E_LHR_LicenseOK_Pending : DINT := 16#203,
E_LHR_LicenseOK_Demo : DINT := 16#254,
E_LHR_LicenseOK_OEM : DINT := 16#255,
//error
E_LHR_LicenseNoFound : DINT := DWORD_TO_DINT(16#98110700+16#24),
E_LHR_LicenseExpired : DINT := DWORD_TO_DINT(16#98110700+16#25),
E_LHR_LicenseExceeded : DINT := DWORD_TO_DINT(16#98110700+16#26),
E_LHR_LicenseInvalid : DINT := DWORD_TO_DINT(16#98110700+16#27),
E_LHR_LicenseSystemIdInvalid : DINT := DWORD_TO_DINT(16#98110700+16#28),
E_LHR_LicenseNoTimeLimit : DINT := DWORD_TO_DINT(16#98110700+16#29),
E_LHR_LicenseTimeInFuture : DINT := DWORD_TO_DINT(16#98110700+16#2A),
E_LHR_LicenseTimePeriodToLong : DINT := DWORD_TO_DINT(16#98110700+16#2B),
E_LHR_DeviceException : DINT := DWORD_TO_DINT(16#98110700+16#2C),
E_LHR_LicenseDuplicated : DINT := DWORD_TO_DINT(16#98110700+16#2D),
E_LHR_SignatureInvalid : DINT := DWORD_TO_DINT(16#98110700+16#2E),
E_LHR_CertificateInvalid : DINT := DWORD_TO_DINT(16#98110700+16#2F),
E_LHR_LicenseOemNotFound : DINT := DWORD_TO_DINT(16#98110700+16#30),
E_LHR_LicenseRestricted : DINT := DWORD_TO_DINT(16#98110700+16#31),
E_LHR_LicenseDemoDenied : DINT := DWORD_TO_DINT(16#98110700+16#32),
E_LHR_LicensePlatformLevelInv : DINT := DWORD_TO_DINT(16#98110700+16#33)
)DINT;
END_TYPE
Value | Meaning |
---|---|
E_LHR_LicenseOK | License is valid |
E_LHR_LicenseOK_Pending | Validation of the licensing device (e.g. License Key Terminal) required |
E_LHR_LicenseOK_Demo | Trial license is valid |
E_LHR_LicenseOK_OEM | OEM license is valid |
E_LHR_LicenseNoFound | Missing license |
E_LHR_LicenseExpired | License expired |
E_LHR_LicenseExceeded | License has too few instances |
E_LHR_LicenseInvalid | License is invalid |
E_LHR_LicenseSystemIdInvalid | Incorrect system ID for the license |
E_LHR_LicenseNoTimeLimit | License not limited in time |
E_LHR_LicenseTimeInFuture | License problem: Time of issue is in the future |
E_LHR_LicenseTimePeriodToLong | License period too long |
E_LHR_DeviceException | Exception at system startup |
E_LHR_LicenseDuplicated | License data read multiple times |
E_LHR_SignatureInvalid | Invalid signature |
E_LHR_CertificateInvalid | Invalid certificate |
E_LHR_LicenseOemNotFound | OEM license for unknown OEM |
E_LHR_LicenseRestricted | License invalid for the system |
E_LHR_LicenseDemoDenied | Trial license not allowed |
E_LHR_LicensePlatformLevelInv | Invalid platform level for the license |
Determining the license ID of the OEM license
The license ID of the OEM license can be obtained from the corresponding license description file or the license manager.
License description file:
"Manage Licenses" tab of the license manager:
Double-clicking on the row containing the license line opens a window showing the license properties, including the license ID:

The OEM can specify in their PLC application how the system should respond to the presence or absence of the OEM application license. Options include program termination or activation of an additional feature.
System requirements
Operating system:
- At least Windows 7 (or its Embedded version) is required in order to be able to use all the functions for the protection of the application software. Windows XP and Windows CE (Windows Embedded Compact) do not support either the encryption of the boot file or OEM licenses.
TC3 PLC Lib Tc2_Utiltities:
- Use at least version 3/3/24 of the TC3 PLC Lib Tc2_Utilities, as they provide various functions for the comfortable handling of TwinCAT 3 licenses. It is mandatory for the use of TwinCAT 3 dongles for OEM application licenses. The TC3 PLC Lib is included from TwinCAT 3.1 Build 4022.16.
TwinCAT Version:
- The functionalities described above require TwinCAT 3.1 build 4024 or higher.
![]() | Reliable protection only when using the latest TwinCAT 3 version For reliable protection (e.g. secure encryption), always use the latest TwinCAT 3 version. This provides the maximum security. Use at least TwinCAT 3.1 Build 4024.x. |
See also: documentation for the PLC library Tc2_Utilities , section Licensing functions