# Protect a Qt C++ Windows application

Following is a step-by-step procedure to protect a Qt C++ Windows app. Note that the steps below assume you have a QLM License Server already set up.

1\. Launch the QLM Management Console

2\. Create a product from the “Define Product” tab or use the Demo 1.0 product if you are evaluating QLM.&#x20;

3\. Go to the "Protect your application tab":

* Page 1: Select the product to protect and the License Server
* Page 2: Select "Qt C++ Windows Only"
* Page 3: Leave the default settings or customize the look & feel if needed
* Page 4: Select the folder where your Qt C++ source code is located and click Save
* Page 5: Click Finish

4\. Copy the following files to your debug or release folder:

* C:\Program Files\Soraco\QuickLicenseMgr\Redistrib\\.net 4.0\QlmLicenseWizard.exe
* C:\Program Files\Soraco\QuickLicenseMgr\Redistrib\\.net 4.0\QlmLicenseLib.dll
* "Your Product x.y.xml" - this is the XML settings file generated by the "Protect your application" wizard

5\. Open a command prompt as Administrator (Run As Administrator) and execute the register.bat batch file located in the sample folder.

6\. Open your Qt C++ project in your IDE

7\. Add the following to your main MainWindow class header file:

> {% code overflow="wrap" %}
>
> ```cpp
> namespace Qlm {
> class LicenseValidator;
> }
>
> In your main class, add the following functions:
>
> private slots:
>     bool checkLicense();
>     bool checkFiles ();
>     void exitApp();
>     void displayMessage (QString msg);
>
> private:
>     Qlm::LicenseValidator *lv;
>     QString wizardSettingsFile;
>     QString wizardExe;
> ```
>
> {% endcode %}

8\. Add the following code to your MainWindow CPP file, in the constructor:&#x20;

{% code overflow="wrap" %}

```cpp
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString appFolder = QDir::currentPath();

    // You can modify these paths depending on where you deploy the QLM files.
    wizardSettingsFile = QDir(appFolder).filePath("Demo 1.0.lw.xml");

    // Note that QlmLicenseLib.dll must be located in the same folder as QlmLicenseWizard.exe
    wizardExe = QDir(appFolder).filePath("QlmLicenseWizard.exe");

    checkFiles();

    lv = new Qlm::LicenseValidator;
    checkLicense ();

}
```

{% endcode %}

9\. Add the following functions to your main class:

{% code overflow="wrap" %}

```cpp
bool MainWindow::checkFiles()
{
    if(QFileInfo(wizardSettingsFile).exists() == false)
    {
        QString msg = QString ("The file \"%1\" does not exist.").arg (wizardSettingsFile);
        displayMessage(msg);
        exitApp ();
        return false;
    }

    if(QFileInfo(wizardExe).exists() == false)
    {
        QString msg = QString ("The file \"%1\" does not exist.").arg (wizardExe);
        displayMessage(msg);
        exitApp ();
        return false;
    }

    // Also make sure that QlmLicenseLib.dll is in the same folder as QlmLicenseWizard.exe
    QString qlmLicenseLibDll = wizardExe;
    qlmLicenseLibDll.replace("QlmLicenseWizard.exe", "QlmLicenseLib.dll");
    if(QFileInfo(qlmLicenseLibDll).exists() == false)
    {
        QString msg = QString ("The file \"%1\" does not exist.").arg (qlmLicenseLibDll);
        displayMessage(msg);
        exitApp ();
        return false;
    }
}

bool MainWindow::checkLicense()
{
    bool needsActivation;
    QString returnMsg;
    bool valid = lv->ValidateLicenseAtStartup (QlmLicenseLib::ELicenseBinding_ComputerName, needsActivation, returnMsg);

    if (valid == false)
    {
        QString args = QString (" /settings \"%1\"").arg (wizardSettingsFile);
        if (lv->license != nullptr)
        { 
            // If the call to LaunchProcess does not launch the wizard
            // the most likely reason is that you have not registered the QlmLicenseLib.dll
            // To register QlmLicenseLib.dll, launch register.bat from a command prompt running
            // as Administrator
            int exitCode = lv->license->LaunchProcess(wizardExe, args, true, true);

            valid = lv->ValidateLicenseAtStartup(QlmLicenseLib::ELicenseBinding_ComputerName,                                             needsActivation, returnMsg);

            if (valid == false)
            {
                QTimer::singleShot(250, qApp, SLOT(quit()));
            }
        }
    }

    if (valid && (returnMsg.length() == 0))
    {
        ui->status_label->setText("The license is valid.");
    }
    else
    {
        ui->status_label->setText(returnMsg);
    }

    return valid;
}

void MainWindow::exitApp()
{
    QTimer::singleShot(250, qApp, SLOT(quit()));
}

void MainWindow::displayMessage (QString msg)
{
    QMessageBox msgBox;
    msgBox.setText("License Error");
    msgBox.setInformativeText(msg);
    msgBox.setStandardButtons(QMessageBox::Ok);
    msgBox.setDefaultButton(QMessageBox::Ok);
    int ret = msgBox.exec();
}
```

{% endcode %}

&#x20;This completes the integration. To generate a license key for testing purposes:

* Go to the Manage Keys tab.
* Click "Create Activation Key"
* Select the Product (Demo 1.0 for trials) and click OK.
* Copy and Paste the generated Activation Key in the License Wizard launched when your application starts up and follow the steps in the wizard.

The files that you need to distribute with your application are:

* QlmLicenseLib.dll
* QlmLicenseWizard.exe
* XML file generated by the Protect Your Application Wizard

#### Troubleshooting

* Missing atlbase.h, strongname.h, metahost.h?

For Qt6, when installing Visual Studio, select the **Individual Components** tab, and under *SDKs, libraries, and frameworks* make sure **Active Qt (**&#x56;isual C++ ATL Suppor&#x74;**)** is selected.

&#x20;

![](https://support.soraco.co/hc/article_attachments/18520500653076)

&#x20;

For Qt 5, you must install the [.NET Framework Developer Pack](https://dotnet.microsoft.com/en-us/download/visual-studio-sdks) 4.6.2 or later. Once you install it, the file should typically be located in: C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8.1\Include

#### [Final note](https://www.qt.io/blog/2018/02/21/protecting-qt-application-device-hacking-part-2)

To further protect your application against hacking, you should check some of the techniques described in the articles below:

* [Protecting a Qt Application or a Device Against Hacking, Part 1](https://www.qt.io/blog/2018/01/11/protecting-qt-application-device-hacking-part-1)
* [Protecting a Qt Application or a Device Against Hacking, Part 2](https://www.qt.io/blog/2018/02/21/protecting-qt-application-device-hacking-part-2)


---

# 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.soraco.co/docs/step-by-step-guides/protect-a-qt-c++-windows-application.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.
