So passen Sie das Installationsverhalten mit dem Qt Installer Framework an

Software-Entwicklung
2021-03-30
8 Minuten
Qt Installer Framework

In früheren Beiträgen zur Anpassung der Installer-Benutzeroberfläche mit dem Qt Installer Framework haben wir das Thema Skripting kurz angesprochen und beschrieben, wie man der Installer-Benutzeroberfläche benutzerdefinierte Seiten hinzufügt. In diesem Beitrag werden wir viel tiefer in die Materie einsteigen. Sie erfahren, welche Arten von Skripten verfügbar sind und wie man sie im Qt Installer Framework erstellt – und das alles mit einigen praktischen Beispielen. Los geht‘s!

Wenn Sie das Qt-Framework und seine Funktionen nicht kennen, lesen Sie zunächst unseren Blogbeitrag Über Qt und wie man damit GUIs erstellt.

In der Zwischenzeit können Sie unsere Seite Qt-Entwicklungsdienste besuchen.

 

API-Übersicht

Bevor wir mit dem Scripting selbst beginnen, erklären wir, was die Scripting-API ist und wie sie funktioniert.

Im Qt Installer Framework ist die Scripting-API im Grunde eine Reihe von JavaScript-Objekten. Mit dieser API erstellte Skripte verwenden Dateien mit der Erweiterung .qs, die von QJSEngine ausgeführt werden. Sie können Skripte verwenden, um bestimmte Aktionen auszuführen oder das Verhalten des Installers während der Laufzeit zu ändern, beispielsweise durch Hinzufügen benutzerdefinierter Seiten, je nachdem, welche Komponenten für die Installation ausgewählt wurden. Bei Installern gibt es zwei Haupttypen von Skripten: Controller-Skripte und Komponenten-Skripte.

Controller-Skripte werden für die Interaktion mit bestimmten Teilen der Benutzeroberfläche oder Funktionalität des Installers verwendet. Sie können beispielsweise vorhandene Seiten ändern oder Benutzerklicks simulieren, um einige Teile der Installation zu automatisieren. Für jeden Installer kann es nur ein einziges Controller-Skript geben, auf das in der Datei config.xml verwiesen wird.

Komponenten-Skripte werden verwendet, um das Verhalten für ausgewählte Komponenten im Installer zu handhaben, sodass jede Komponente ihr eigenes Skript haben kann. Aus diesem Grund kann jedes Installationsprogramm mehrere Komponentenskripte enthalten. Diese werden ausgeführt, wenn die Komponente zur Installation ausgewählt wird. Das Komponentenskript, das Sie verwenden möchten, muss in der Datei package.xml angegeben sein.

 

Grundlagen von Controller-Skripten

Lassen Sie uns zunächst ein wenig über die Skriptstruktur im Qt Installer Framework sprechen. Sowohl Controller- als auch Komponentenskripte haben fast dieselbe Struktur – der einzige Unterschied zwischen ihnen besteht darin, was Sie im Skript tun können und wie der Konstruktor heißt.

Ein minimal gültiges Skript muss mindestens einen Konstruktor enthalten. Zu Beginn können wir die Datei script.qs erstellen. Damit diese Datei als richtiges Skript erkannt wird, müssen wir den leeren Konstruktor darin einfügen. Im Fall des Controller-Skripts ist dies der folgende Konstruktor:

 

function Controller()
{
}

Lassen Sie uns nun einige einfache Funktionen implementieren, um das Verhalten des Installationsprogramms zu ändern. Nehmen wir an, wir möchten einige Seiten im Installationsprogramm automatisch überspringen – beispielsweise die Einführungsseite. Eine der einfachen Lösungen hierfür besteht darin, einen Klick auf die Schaltfläche „Weiter“ auszulösen, wenn die ausgewählte Seite angezeigt wird. Dazu können wir Controller.prototype.IntroductionPageCallback verwenden. Das Skript sollte wie folgt aussehen:

 

function Controller()
{
}

Controller.prototype.IntroductionPageCallback = function()
{
    gui.clickButton(buttons.NextButton);
}

In diesem Skript haben wir zwei globale Objekte verwendet, auf die in Controller-Skripten zugegriffen werden kann. Das erste ist die GUI, ein globales JavaScript-Objekt, das die Interaktion mit der Benutzeroberfläche des Installationsprogramms ermöglicht. Die Schaltflächen ermöglichen uns, wie der Name schon sagt, die Verwendung von Schaltflächen, die auf Installationsseiten platziert sind. Neben diesen Objekten hat jede Seite einen Satz eigener Methoden, Schaltflächen und Widgets. Auf der Komponentenauswahlseite können Sie beispielsweise Funktionen wie selectAll() oder selectComponent(id) verwenden, um die Komponentenauswahl zu verwalten. Wir werden in diesem Beitrag nicht alle beschreiben, da dies zu lange dauern würde. Wenn Sie sich mit allen verfügbaren Optionen vertraut machen möchten, sehen Sie sich die Dokumentation an.

Um nun das Skript in Ihrem Installationsprogramm zu verwenden, öffnen Sie die Konfigurationsdatei für Ihr Installationsprogramm und fügen Sie ihr einfach das folgende Tag hinzu:

 

<ControlScript>script.qs</ControlScript>

Vergessen Sie nicht, script.qs im Konfigurationsverzeichnis abzulegen! Jetzt ist Ihr erstes Controller-Skript angeschlossen – Sie können ein neues Installationsprogramm generieren und es ausprobieren. Wenn Sie nicht mehr wissen, wie das geht, lesen Sie unseren Beitrag über Bereitstellung von Anwendungen und Generierung von Offline-Installationsprogrammen für Windows Qt Installer Framework Tutorial.

 

Grundlagen von Komponentenskripten

Jetzt haben wir ein funktionsfähiges Controllerskript. Lassen Sie uns das grundlegende Komponentenskript erstellen. Genau wie beim Controllerskript müssen Sie mit einem Konstruktor beginnen – in diesem Fall heißt er Component. Als einfaches Beispiel für ein Komponentenskript verwenden wir das aus dem vorherigen Beitrag über Anpassen der Installer-Benutzeroberfläche mit Qt Installer Framework. Sein Zweck besteht darin, dem Installer eine benutzerdefinierte Seite hinzuzufügen, wenn die Komponente ausgewählt wird. Zur Implementierung können wir die Funktion addWizardPage verwenden:

 

function Component()
{
    installer.addWizardPage(component, "MyOtherPage", QInstaller.ReadyForInstallation);
}

Eine Funktion, die eine neue Seite hinzufügt, benötigt drei Parameter. Der erste ist die Komponente, die den registrierten Namen der Widget-Klasse enthält, die Sie hinzufügen möchten – in diesem Fall wurde ein globales Komponentenobjekt übergeben, das auf die aktuelle Komponente verweist. Das nächste Argument ist der Name der registrierten Widget-Klasse, die Sie verwenden möchten. Der letzte ist der Index der vorhandenen Seite, vor der die neue Seite platziert wird. In diesem Fall würde CustomPage vor der Seite ReadyForInstallation platziert.

Damit dieses Skript funktioniert, müssen Sie auch eine Seiten-UI-Datei hinzufügen, die das Seitendesign im Paketverzeichnis enthält, und diese Datei auch in package.xml registrieren. Außerdem müssen Sie das Skript in package.xml angeben, damit es ausgeführt wird:

 

<Script>installscript.qs</Script>
<UserInterfaces>
    <UserInterface>CustomPage.ui</UserInterface>
</UserInterfaces>

Wenn Sie mehr über das Anpassen der Benutzeroberfläche des Installationsprogramms erfahren möchten, sehen Sie sich den Beitrag zum Thema Anpassen der Benutzeroberfläche des Installationsprogramms mit Qt Installer Framework an.

 

Verknüpfung hinzufügen

Da Sie nun mit den Grundlagen des Schreibens von Skripten vertraut sind, können wir nun zu fortgeschritteneren Anwendungsfällen mit Beispielen übergehen. Nehmen wir an, wir haben ein Windows-App-Installationsprogramm und möchten nach Abschluss einer Installation eine App-Verknüpfung auf dem Desktop erstellen. Um eine solche Funktionalität zu implementieren, können wir das Komponentenskript verwenden, da für verschiedene Pakete unterschiedliche ausführbare Dateien verwendet werden können.

Wir müssen lediglich eine benutzerdefinierte Operation hinzufügen, die ausgeführt wird, wenn die Komponente installiert wird. Dazu können wir den Hook Component.prototype.createOperations mit der Funktion addOperation verwenden:

 

function Component()
{
    // default constructor
}

Component.prototype.createOperations = function()
{
    try {
        // call the base create operations function
        component.createOperations();
        // check if we are on widnows machine
        if (installer.value("os") == "win") {
            try {
                // look for user profile directory
                var userProfile = installer.environmentVariable("USERPROFILE");
                installer.setValue("UserProfile", userProfile);
                component.addOperation("CreateShortcut", "@TargetDir@\\win64\\application.exe", "@UserProfile@\\Desktop\\My\ App.lnk");                
            } catch (e) {
                // Do nothing if key doesn't exist
            }
        }
    } catch (e) {
        print(e);
    }
}

 

Rekursive Installation

Es kann vorkommen, dass trotz Bibliotheken und anderen Dateien, die Sie einfach in den Bereitstellungsordner legen können, einige externe Tools erforderlich sind, damit Ihre App auf dem Endgerät funktioniert. Ein häufiges Beispiel für einen solchen Fall sind Microsoft Visual C++ Redistributable-Pakete mit C- und C++-Laufzeit, die auf dem Gerät benötigt werden, wenn Sie eine App mit einem MVSC-Kit kompiliert haben.

Sie können einfach Laufzeit-DLL-Dateien in den Bereitstellungsordner legen, allerdings gibt es einen Haken. Antivirensoftware verwendet nicht gerne C- und C++-Laufzeitbibliotheken, die nicht mit dem Microsoft-Installationsprogramm installiert wurden, da geänderte Laufzeiten auf dem Computer des Benutzers einige böse Dinge anrichten können. Mit diesem Ansatz kann Ihre App als bösartig erkannt werden, und so etwas möchten Sie nie. Was sollten Sie tun?

Die Lösung ist ganz einfach: Führen Sie eine rekursive Installation der Redistributable-Pakete durch. Das klingt vielleicht kompliziert und ist schwer umzusetzen, aber im Grunde geht es darum, zu prüfen, ob auf dem Gerät eine VC-Laufzeitumgebung vorhanden ist, und, falls nicht, das Installationsprogramm für weiterverteilbare Pakete von Microsoft auszuführen. Sehen wir uns an, wie das geht.

Als Erstes müssen Sie ein Installationsprogramm für weiterverteilbare Pakete von der Microsoft-Website herunterladen. Danach legen Sie es im Datenordner des Pakets ab.

Nun beginnen wir mit dem Skripting. Da wir mit einer einzelnen Komponente arbeiten, benötigen wir ein Komponentenskript. Zunächst müssen wir eine benutzerdefinierte Funktion erstellen, mit der wir nach einer vorhandenen VC-Laufzeit suchen und das Installationsprogramm ausführen können, wenn diese fehlt:

 

Component.prototype.installVCRedist = function()
{
    var registryVC2017x64 = installer.execute("reg", new Array("QUERY", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x64", "/v", "Installed"))[0];

    if (registryVC2017x64)
    {
        QMessageBox.information("vcRedist.install", "Install VS Redistributables", "The application requires Visual Studio 2017 Redistributables. Please follow the steps to install it now.", QMessageBox.OK);
        var dir = installer.value("TargetDir");
        installer.execute(dir + "/VC_redist.x64.exe", "/norestart", "/passive");
    }
}

In dieser Funktion überprüfen wir zunächst die Systemregister, um zu überprüfen, ob eine VC-Runtime installiert ist. Wenn die Installation erforderlich ist, wird ein Meldungsfeld mit den entsprechenden Informationen angezeigt. Nach dem Klicken auf „OK“ wird das Installationsprogramm ausgeführt. Wir verwenden den Pfad „TargetDir“, da das VC-Runtime-Installationsprogramm am selben Ort abgelegt wird wie das Stammverzeichnis der installierten App.

Nachdem die Installation der Komponente abgeschlossen ist, muss nur noch die Funktion ausgeführt werden. Dazu können wir das Signal- und Slots-System verwenden, das auch in der Skript-Engine verfügbar ist:

 

function Component()
{
    // constructor
    installer.installationFinished.connect(this, Component.prototype.installVCRedist);
}

 

Zusammenfassung

In diesem Beitrag haben Sie gelernt, was die Scripting-API im Qt Installer Framework ist und wie man sie verwendet. Mit diesem neuen Wissen können Sie jetzt mit den Installer-Skripten spielen und experimentieren, da die Anwendungsmöglichkeiten endlos sind. Es gibt noch viel mehr beliebte Anwendungsfälle für Skripte als die in diesem Beitrag vorgestellten. In zukünftigen Beiträgen werden wir mehr davon vorstellen, also bleiben Sie dran.

Wenn Ihnen dieser Beitrag gefällt, abonnieren Sie unseren Newsletter und bleiben Sie auf dem Laufenden.

 

Scythe-Studio - Blog Redactors

Scythe Studio Blog Redactors

Brauchen Sie Qt QML-Entwicklungsdienste?

service partner

Kommen wir zur Sache: Es ist eine Herausforderung, Top-Qt-QML-Entwickler zu finden. Helfen Sie sich selbst und starten Sie die Zusammenarbeit mit Scythe Studio – echten Experten im Qt C++ Framework.

Entdecken Sie unsere Fähigkeiten!

Neueste Artikel

[ 157 ]