# Handling Product Versions

Product versioning empowers vendors to introduce fresh iterations of their licensed products, fostering increased customization.

This article serves to educate readers on a range of topics, including defining and retrieving application versions, implementing conditional update checks within maintenance windows, validating product versions during license checks, and other relevant insights.

### Prerequisites

* Completed the Getting Started tutorials, specifically:
  * Initialized LicenseManager (or LicenseHandler) with your configuration using the appropriate settings.
  * Activated a license.

### Defining App Version

Setting application version is completed within the `Configuration` constructor, as shown below:

{% tabs %}
{% tab title="C++" %}

```cpp
std::shared_ptr<Configuration> pConfiguration = Configuration::Create( 
  EncryptStr("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"),
  EncryptStr("XXXXXXXXX-XXXXX-XXXXXXXXXXXXX_XXXXXX_XXXXXX"), 
  EncryptStr("XXXXXX"), 
  appName, appVersion, options);
```

{% endtab %}

{% tab title="C#" %}

```csharp
var configuration = new LicenseSpring.Configuration(
  apiKey: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  sharedKey: "XXXXXXXXX-XXXXX-XXXXXXXXXXXXX_XXXXXX_XXXXXX",
  productCode: "PRODUCT SHORT CODE",
  appName: "My application",
  appVersion: "v5.2" );
```

{% endtab %}

{% tab title="Java" %}

```java
LicenseSpringConfiguration configuration = LicenseSpringConfiguration.builder()
                .apiKey( "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" )
                .productCode( "javaproduct" )
                .sharedKey( "XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXX" )
                .appName( "NAME" )
                .appVersion( "VERSION" )
                .build();
```

{% endtab %}

{% tab title="Swift" %}

```swift
let configuration = Configuration(
    apiKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    sharedKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    productCode: "XX"
)
configuration.appName = "My LicenseSpring Application"
configuration.appVersion = "1.0.0"
```

{% endtab %}

{% tab title="Python" %}

```python
import licensespring

licensespring.app_version = "MyApp 1.0.0"
```

{% endtab %}
{% endtabs %}

The fifth parameter passed, `appVersion`, is where the version is set for the application.

From here, current app version can be accessed with:

{% tabs %}
{% tab title="C++" %}

```cpp
appVersion = pConfiguration->getAppVersion();
```

{% endtab %}

{% tab title="C#" %}

```csharp
appVersion = pConfiguration.AppVersion();
```

{% endtab %}

{% tab title="Java" %}

```java
appVersion = pConfiguration.getAppVersion();
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.appVersion
```

{% endtab %}
{% endtabs %}

To access a list of all available product versions, we can use `getVersionList()` from the `LicenseManager` object. Acquiring a vector of strings containing all versions is done with:

{% tabs %}
{% tab title="C++" %}

```cpp
listVersions = licenseManager->getVersionList(licenseId);
```

{% endtab %}

{% tab title="C#" %}

```csharp
listVersions = licenseManager.GetAllVersions( licenseId );
```

{% endtab %}

{% tab title="Java" %}

```java
listVersions = licenseManager.getVersions( licenseIdentity );
```

{% endtab %}

{% tab title="Swift" %}

```swift
let versions = try license.requestAvailableVersions() // [AvailableVersion].
```

{% endtab %}

{% tab title="Python" %}

```python
response = manager.get_version_list(license_id=license_id)
```

{% endtab %}
{% endtabs %}

### Retrieving Installation Files

#### Getting Latest Installation File During Online License Check

To confirm the latest product version during a license check, we'll construct an `InstallationFile` object and assign it the value obtained from `license->check()`.

As `license->check()` furnishes the most recent `InstallationFile` associated with the license, we can subsequently access the version information by executing:

{% tabs %}
{% tab title="C++" %}

```cpp
InstallationFile::ptr_t ins = license->check();
std::string version = ins->version();
```

{% endtab %}

{% tab title="C#" %}

```csharp
InstallationFile::ptr_t ins = license.Check();
std::string version = ins.Version();
```

{% endtab %}

{% tab title="Swift" %}

```swift
try license.fullCheck()
if let installationFile = license.installationFile { ... }
```

{% endtab %}
{% endtabs %}

#### Getting All Installation Files

Developers can also retrieve the latest `InstallationFile` releases through the `LicenseManager` object through use of the `licenseID` as follows:

{% tabs %}
{% tab title="C++" %}

```cpp
licenseManager->getInstallationFile(licenseID);
```

{% endtab %}

{% tab title="C#" %}

```csharp
licenseManager.GetInstallationFile( licenseID );
```

{% endtab %}

{% tab title="Java" %}

```java
licenseManager.getInstallationFile( licenseIdentity );
```

{% endtab %}

{% tab title="Swift" %}

```swift
let specificVersion = try license.requestInstallationFile(version: "x.y.z")
```

{% endtab %}

{% tab title="Python" %}

```python
response = manager.get_installation_file(license_id=license_id)

print(response)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note:

The C++ `getInstallationFile()` method has two additional, optional parameters. The second parameter is to declare a desired product version, if not provided then the last available version will be assumed. The third parameter is a `InstallFileFilter` object that can be used to filter install files by environment and channel.

The .NET SDK has one additional parameter, an `InstallationFileOptions` object that can be used to filter install files by channel or environment, as well as the needed version.
{% endhint %}

{% hint style="danger" %}
Exceptions called if an installation file is not found for requested app version:

C++: ProductVersionException

.NET: AppVersionNotFoundException

Java: LicenseSpringException
{% endhint %}

#### InstallationFile Class Overview and Intermediate Updates

The `InstallationFile` class holds crucial information about a product's installation file.

It captures details about the product installer or setup file uploaded via the LicenseSpring platform or Management API, facilitating efficient product versioning and management.

Installation files can be used to regulate intermediate updates through accessing the required app version to complete the update

An intermediate update denotes an update that mandates a specific version of the predictor to be presently installed.

You can verify the necessary version by utilizing `InstallationFile` as follows:

{% tabs %}
{% tab title="C++" %}

```cpp
requiredVersion = installationFile->requiredVersion();
```

{% endtab %}

{% tab title="C#" %}

```csharp
requiredVersion = installationFile->RequiredVersion();
```

{% endtab %}

{% tab title="Swift" %}

```swift
if let requiredVersion = installationFile.requiredVersion { ... }
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.licensespring.com/sdks/tutorials/best-practices/handling-product-versions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
