
Quote from luishp on August 2, 2026, 9:15 pmVisualNEO Win now includes an optional offline application licensing system. It allows developers to distribute compiled applications that require a valid customer-specific license before they can run.
Licensing is disabled by default, so existing projects continue to work exactly as before.
The system does not require an Internet connection or an activation server. Licenses are verified locally using modern public-key cryptography.
How the licensing system works
The system uses two cryptographic keys:
- A private key, which is used by the developer to create and sign licenses.
- A public key, which is included in the VisualNEO Win application and is used only to verify licenses.
The private key must remain exclusively under the developer's control. The compiled application contains only the public key, so it cannot create new licenses or modify existing ones.
Each license may contain:
- Product identifier
- License identifier
- Customer name
- Customer email
- Edition
- Optional feature names
- Issue date
- Optional expiry date
Licenses are stored as
.vnlicensefiles.
1. Create your author key
Open:
VNLicenseManager.exeThis program is included with the Universal version of VisualNEO Win.
Select New key and save the generated
.vnkeyfile in a secure location.The License Manager will display the corresponding public key. You will need to copy this public key into your VisualNEO Win project.
Important
The
.vnkeyfile is your private signing key.Keep it protected and create at least one secure backup. Anyone who obtains this file can create apparently valid licenses for your product.
Never include the
.vnkeyfile in:
- A compiled application
- A VisualNEO Win PUB file
- An installer
- A ZIP or distribution package
- A support attachment
- A public repository
- A customer backup
The included file named:
DEMO-ONLY-author.vnkeyis intentionally public and must never be used for a real commercial product.
2. Configure licensing in your VisualNEO Win project
Open your publication and go to:
App Properties > Security > Application LicensingEnable application licensing and configure the following values.
Product ID
Enter a stable identifier for your product, for example:
com.mycompany.myproductor:
MYCOMPANY-MYAPPLICATIONThe exact format is your choice, but it must remain unchanged in future versions of the same product.
A license created for one Product ID cannot be used with another Product ID.Public key
Paste the public key displayed by VisualNEO License Manager.
The public key is not secret and can safely be stored in the PUB file and compiled application.License filename
Specify the filename that the application will use, for example:
myapplication.vnlicenseDialog title
You can customize the title of the registration dialog shown when a valid license cannot be found.
For example:
My Application RegistrationPurchase URL
Optionally enter a web address where users can purchase or request a license.
After saving these settings, licensing will be applied when you compile the standalone application.
3. Create a customer license
Open VisualNEO License Manager and load your private
.vnkeyfile.
Enter the same Product ID that you configured in your VisualNEO Win project.You can then enter the customer's information:
- License ID
- Customer name
- Customer email
- Edition
- Optional features
- Issue date
- Optional expiry date
Dates must use the ISO format:
YYYY-MM-DDFor example:
2026-08-02The expiry date is inclusive. A license expiring on
2027-08-02will remain valid throughout that date.
If the license should never expire, leave the expiry field empty.
Press the appropriate issue or save button to generate the.vnlicensefile, and send that file to the customer.
4. Install the license on the customer's computer
When the compiled application starts, it looks for the license in two locations.
First, it checks beside the application executable:MyApplication.exe MyApplication.vnlicenseThis is useful for portable applications.
If no valid portable license is found, it checks the user's local application data folder:
%LOCALAPPDATA%\VisualNeoWin\Licenses\<product-id>\<license-filename>The customer does not normally need to locate this folder manually.
If the application cannot find a valid license, it displays a registration dialog. The customer can:
- Import a
.vnlicensefile- Paste a complete license token
- Open the configured purchase page
- Cancel and close the application
When a license is imported, VisualNEO Win copies it to the correct per-user folder automatically.
Licensing is therefore per Windows user unless the license file is placed beside the application executable.
5. Testing your licensed application
Publications run from inside VisualNEO Win use development mode and do not block the author with the registration dialog.
Development mode allows you to continue designing and testing the project even if no customer license has been installed.
To test the real licensing process, compile the project as a standalone EXE and run the compiled application.The standalone application will:
- Search for the configured license.
- Verify its digital signature.
- Confirm that the Product ID matches.
- Check the issue and expiry dates.
- Display the registration dialog if validation fails.
Cancelling the registration dialog closes the application.
6. License variables available in NeoScript
VisualNEO Win automatically creates the following global variables (only for licensed applications):
[LicenseEnabled] [LicenseProductID] [LicensePublicKey] [LicenseFileName] [LicenseDialogTitle] [LicensePurchaseURL] [LicenseValid] [LicenseStatus] [LicenseName] [LicenseEmail] [LicenseExpires] [LicenseID] [LicenseEdition] [LicenseFeatures]You can find them under the Global tab of the Application Variables dialog.
Some of the most useful variables are:
[LicenseValid]Indicates whether the current license is valid.
[LicenseStatus]Contains the current validation status or development-mode status.
[LicenseName]Contains the licensed customer's name.
[LicenseEmail]Contains the customer's email address.
[LicenseEdition]Contains the edition specified when the license was created.
[LicenseFeatures]Contains the comma-separated list of licensed features.
[LicenseExpires]Contains the license expiry date, when one exists.
The configuration variables are informational snapshots. Changing values such as
[LicenseProductID]or[LicensePublicKey]from NeoScript does not alter the actual licensing configuration.
7. NeoScript licensing actions
VisualNEO Win provides several NeoScript actions for working with licenses.
Validate the current license
LicenseValidate "[Result]" "[Error]"This validates the currently installed license and updates the license variables.
Example:
LicenseValidate "[Result]" "[Error]" If "[Result]" "=" "True" AlertBox "License" "The license is valid." Else AlertBox "License error" "[Error]" EndIf
Install a license
LicenseInstall "token-or-file" "[Result]" "[Error]"The first parameter may be either:
- The path to a
.vnlicensefile- A complete license token
Example:
FileOpenBox "Select license" "License files|*.vnlicense" "" "[LicensePath]" If "[LicensePath]" "<>" "" LicenseInstall "[LicensePath]" "[Result]" "[Error]" If "[Result]" "=" "True" AlertBox "License" "The license has been installed." Else AlertBox "License error" "[Error]" EndIf EndIf
Remove the installed license
LicenseRemove "[Result]" "[Error]"Example:
LicenseRemove "[Result]" "[Error]" If "[Result]" "=" "True" AlertBox "License" "The installed license has been removed." Else AlertBox "License error" "[Error]" EndIf
Read an individual license field
LicenseGetField "field" "[Result]"Supported fields are:
product_id license_id name email edition features issued expiresExample:
LicenseGetField "edition" "[Edition]" AlertBox "License edition" "[Edition]"
Check whether a feature is licensed
LicenseHasFeature "feature" "[Result]"Feature names are compared without regard to uppercase or lowercase characters.
For example, suppose a license was created with these features:PDFExport,AdvancedReports,CloudBackupYour application can check for one of them:
LicenseHasFeature "PDFExport" "[HasPDFExport]" If "[HasPDFExport]" "=" "True" GoToPage "PDF Export" Else AlertBox "Feature unavailable" "PDF export is not included in your license." EndIfThis makes it possible to distribute one application while enabling different functions according to the customer's license.
Show the registration dialog
LicenseShowDialog "[Result]"This displays the standard application licensing dialog manually.
Example:LicenseShowDialog "[Result]"You might use this action from a menu option such as:
Help > Install License
8. Using editions and features
The licensing system supports both editions and individual features.
For example, you could create these editions:Standard Professional EnterpriseYou could then check
[LicenseEdition]inside NeoScript:If "[LicenseEdition]" "=" "Enterprise" ShowObject "EnterprisePanel" Else HideObject "EnterprisePanel" EndIfAlternatively, you can define specific features:
ExportPDF MultiUser AdvancedReports CustomBrandingFeature checks are usually more flexible than relying only on edition names.
For example:
LicenseHasFeature "AdvancedReports" "[HasAdvancedReports]" If "[HasAdvancedReports]" "=" "True" EnableObject "AdvancedReportsButton" Else DisableObject "AdvancedReportsButton" EndIf
9. Updating your application
For routine updates of the same application, keep the same:
- Product ID
- Public key
- Private
.vnkeyfile- License filename, unless you have a specific reason to change it
Existing customer licenses will then continue to work with the updated application.
Do not generate a new author key for every release. A new key would cause all licenses signed with the previous private key to be rejected.
Create a new key only when you deliberately want to establish a new licensing identity or when the previous private key has been compromised.
10. Security considerations
The licensing system uses ECDSA P-256 digital signatures and SHA-256 through the Windows Cryptography API.
This provides strong protection against:
- Editing customer information inside a license
- Changing the expiry date
- Adding unauthorized features
- Reusing a license with another Product ID
- Creating new licenses without the private key
However, this is an offline application licensing system, not a complete anti-tamper or digital rights management platform.
A determined attacker with sufficient reverse-engineering experience may attempt to modify the compiled application and bypass its license checks.For greater protection, developers may combine VisualNEO licensing with tools such as Obsidium. In that configuration:
- VisualNEO licensing verifies that the customer license is authentic.
- Obsidium protects the compiled executable against modification and reverse engineering.
These are complementary layers.
Current limitations
The first version intentionally does not include:
- Online activation
- Machine-bound licenses
- License revocation
- Floating or network licenses
- Server-controlled subscriptions
- Protection against Windows clock rollback
- Hardware-backed private keys
- Built-in anti-tamper protection
Machine binding was deliberately omitted because hardware changes frequently create additional support requests.
License expiry is checked using the local Windows date. Since validation is completely offline, manually changing the computer clock is not currently prevented.
Example project
VisualNEO Win includes complete application licensing samples in English and Spanish.
You can find them in:
NeoBook\Build\Modern Samples\English\04 Application Licensingand:
NeoBook\Build\Modern Samples\Spanish\04 Licencias de AplicacionesEach sample includes:
- A readable PUB project
- A sample license
- The public key
- The sample Product ID
- A README file
- An intentionally unsafe demo-only private key
- Buttons demonstrating all licensing NeoScript actions
The sample private key must only be used for testing.
Recommended workflow summary
- Create one private
.vnkeyfile for the product.- Back it up securely.
- Copy its public key.
- Enable licensing in App Properties > Security > Application Licensing.
- Define a permanent Product ID.
- Paste the public key.
- Compile the application.
- Use VisualNEO License Manager to create a customer
.vnlicense.- Send the license to the customer.
- Keep the same Product ID and author key for future updates.
This system allows VisualNEO Win developers to protect applications, issue customer-specific offline licenses, create expiring licenses, define commercial editions, and enable individual features without operating an activation server.
VisualNEO Win now includes an optional offline application licensing system. It allows developers to distribute compiled applications that require a valid customer-specific license before they can run.
Licensing is disabled by default, so existing projects continue to work exactly as before.
The system does not require an Internet connection or an activation server. Licenses are verified locally using modern public-key cryptography.
The system uses two cryptographic keys:
The private key must remain exclusively under the developer's control. The compiled application contains only the public key, so it cannot create new licenses or modify existing ones.
Each license may contain:
Licenses are stored as .vnlicense files.
Open:
VNLicenseManager.exe
This program is included with the Universal version of VisualNEO Win.
Select New key and save the generated .vnkey file in a secure location.
The License Manager will display the corresponding public key. You will need to copy this public key into your VisualNEO Win project.
The .vnkey file is your private signing key.
Keep it protected and create at least one secure backup. Anyone who obtains this file can create apparently valid licenses for your product.
Never include the .vnkey file in:
The included file named:
DEMO-ONLY-author.vnkey
is intentionally public and must never be used for a real commercial product.
Open your publication and go to:
App Properties > Security > Application Licensing
Enable application licensing and configure the following values.
Enter a stable identifier for your product, for example:
com.mycompany.myproduct
or:
MYCOMPANY-MYAPPLICATION
The exact format is your choice, but it must remain unchanged in future versions of the same product.
A license created for one Product ID cannot be used with another Product ID.
Paste the public key displayed by VisualNEO License Manager.
The public key is not secret and can safely be stored in the PUB file and compiled application.
Specify the filename that the application will use, for example:
myapplication.vnlicense
You can customize the title of the registration dialog shown when a valid license cannot be found.
For example:
My Application Registration
Optionally enter a web address where users can purchase or request a license.
After saving these settings, licensing will be applied when you compile the standalone application.
Open VisualNEO License Manager and load your private .vnkey file.
Enter the same Product ID that you configured in your VisualNEO Win project.
You can then enter the customer's information:
Dates must use the ISO format:
YYYY-MM-DD
For example:
2026-08-02
The expiry date is inclusive. A license expiring on 2027-08-02 will remain valid throughout that date.
If the license should never expire, leave the expiry field empty.
Press the appropriate issue or save button to generate the .vnlicense file, and send that file to the customer.
When the compiled application starts, it looks for the license in two locations.
First, it checks beside the application executable:
MyApplication.exe
MyApplication.vnlicense
This is useful for portable applications.
If no valid portable license is found, it checks the user's local application data folder:
%LOCALAPPDATA%\VisualNeoWin\Licenses\<product-id>\<license-filename>
The customer does not normally need to locate this folder manually.
If the application cannot find a valid license, it displays a registration dialog. The customer can:
.vnlicense fileWhen a license is imported, VisualNEO Win copies it to the correct per-user folder automatically.
Licensing is therefore per Windows user unless the license file is placed beside the application executable.
Publications run from inside VisualNEO Win use development mode and do not block the author with the registration dialog.
Development mode allows you to continue designing and testing the project even if no customer license has been installed.
To test the real licensing process, compile the project as a standalone EXE and run the compiled application.
The standalone application will:
Cancelling the registration dialog closes the application.
VisualNEO Win automatically creates the following global variables (only for licensed applications):
[LicenseEnabled]
[LicenseProductID]
[LicensePublicKey]
[LicenseFileName]
[LicenseDialogTitle]
[LicensePurchaseURL]
[LicenseValid]
[LicenseStatus]
[LicenseName]
[LicenseEmail]
[LicenseExpires]
[LicenseID]
[LicenseEdition]
[LicenseFeatures]
You can find them under the Global tab of the Application Variables dialog.
Some of the most useful variables are:
[LicenseValid]Indicates whether the current license is valid.
[LicenseStatus]Contains the current validation status or development-mode status.
[LicenseName]Contains the licensed customer's name.
[LicenseEmail]Contains the customer's email address.
[LicenseEdition]Contains the edition specified when the license was created.
[LicenseFeatures]Contains the comma-separated list of licensed features.
[LicenseExpires]Contains the license expiry date, when one exists.
The configuration variables are informational snapshots. Changing values such as [LicenseProductID] or [LicensePublicKey] from NeoScript does not alter the actual licensing configuration.
VisualNEO Win provides several NeoScript actions for working with licenses.
LicenseValidate "[Result]" "[Error]"
This validates the currently installed license and updates the license variables.
Example:
LicenseValidate "[Result]" "[Error]"
If "[Result]" "=" "True"
AlertBox "License" "The license is valid."
Else
AlertBox "License error" "[Error]"
EndIf
LicenseInstall "token-or-file" "[Result]" "[Error]"
The first parameter may be either:
.vnlicense fileExample:
FileOpenBox "Select license" "License files|*.vnlicense" "" "[LicensePath]"
If "[LicensePath]" "<>" ""
LicenseInstall "[LicensePath]" "[Result]" "[Error]"
If "[Result]" "=" "True"
AlertBox "License" "The license has been installed."
Else
AlertBox "License error" "[Error]"
EndIf
EndIf
LicenseRemove "[Result]" "[Error]"
Example:
LicenseRemove "[Result]" "[Error]"
If "[Result]" "=" "True"
AlertBox "License" "The installed license has been removed."
Else
AlertBox "License error" "[Error]"
EndIf
LicenseGetField "field" "[Result]"
Supported fields are:
product_id
license_id
name
email
edition
features
issued
expires
Example:
LicenseGetField "edition" "[Edition]"
AlertBox "License edition" "[Edition]"
LicenseHasFeature "feature" "[Result]"
Feature names are compared without regard to uppercase or lowercase characters.
For example, suppose a license was created with these features:
PDFExport,AdvancedReports,CloudBackup
Your application can check for one of them:
LicenseHasFeature "PDFExport" "[HasPDFExport]"
If "[HasPDFExport]" "=" "True"
GoToPage "PDF Export"
Else
AlertBox "Feature unavailable" "PDF export is not included in your license."
EndIf
This makes it possible to distribute one application while enabling different functions according to the customer's license.
LicenseShowDialog "[Result]"
This displays the standard application licensing dialog manually.
Example:
LicenseShowDialog "[Result]"
You might use this action from a menu option such as:
Help > Install License
The licensing system supports both editions and individual features.
For example, you could create these editions:
Standard
Professional
Enterprise
You could then check [LicenseEdition] inside NeoScript:
If "[LicenseEdition]" "=" "Enterprise"
ShowObject "EnterprisePanel"
Else
HideObject "EnterprisePanel"
EndIf
Alternatively, you can define specific features:
ExportPDF
MultiUser
AdvancedReports
CustomBranding
Feature checks are usually more flexible than relying only on edition names.
For example:
LicenseHasFeature "AdvancedReports" "[HasAdvancedReports]"
If "[HasAdvancedReports]" "=" "True"
EnableObject "AdvancedReportsButton"
Else
DisableObject "AdvancedReportsButton"
EndIf
For routine updates of the same application, keep the same:
.vnkey fileExisting customer licenses will then continue to work with the updated application.
Do not generate a new author key for every release. A new key would cause all licenses signed with the previous private key to be rejected.
Create a new key only when you deliberately want to establish a new licensing identity or when the previous private key has been compromised.
The licensing system uses ECDSA P-256 digital signatures and SHA-256 through the Windows Cryptography API.
This provides strong protection against:
However, this is an offline application licensing system, not a complete anti-tamper or digital rights management platform.
A determined attacker with sufficient reverse-engineering experience may attempt to modify the compiled application and bypass its license checks.
For greater protection, developers may combine VisualNEO licensing with tools such as Obsidium. In that configuration:
These are complementary layers.
The first version intentionally does not include:
Machine binding was deliberately omitted because hardware changes frequently create additional support requests.
License expiry is checked using the local Windows date. Since validation is completely offline, manually changing the computer clock is not currently prevented.
VisualNEO Win includes complete application licensing samples in English and Spanish.
You can find them in:
NeoBook\Build\Modern Samples\English\04 Application Licensing
and:
NeoBook\Build\Modern Samples\Spanish\04 Licencias de Aplicaciones
Each sample includes:
The sample private key must only be used for testing.
.vnkey file for the product..vnlicense.This system allows VisualNEO Win developers to protect applications, issue customer-specific offline licenses, create expiring licenses, define commercial editions, and enable individual features without operating an activation server.