Die Installationsskripte#

Die Installationsskripte sind wie INI-Dateien aufgebaut und in Sektionen aufgeteilt.

Sektionen#

Ein Installationsskript besteht immer aus zwei Sektionen: Initial und Actions. Die weiteren Sektionen werden unter der Actions-Sektion gelistet und bilden den Ablauf der für die Installation benötigten Schritte ab.

Im Folgenden wird der Zweck einige Funktionen erläutert:

Initial-Sektion#

In dieser Sektion werden die einleitenden Anweisungen notiert. In der folgenden Tabelle sind die gängigsten Aufrufe gelistet:

Schlüssel

Beschreibung

Message

Der Name des Produkts wird mit Hersteller angegeben, gefolgt von drei Punkten. ((De-)Installiere Produkt…)

SetLogLevel

Stufe mit der Log-Dateien erstellt werden (Standard: 6, maximal 9)

DefVar

Definition von Variablen

Beispiel:

[Initial]
Message=Produkt...
DefVar $ExitCode$
SetLogLevel=5

Actions-Sektion#

In dieser Sektion wird der Ablauf der Installation festgelegt. Nach dem Deklarieren der Sektion, folgt die Anweisung ShowBitmap "Pfad" "Text", die für das Anzeigen des Logos mit einem kleinen Text sorgt. Darauf folgen Anweisung entsprechend der Dokumentation von der Firma ubi gmbh. Die wichtigsten sind:

Sektion

Beschreibung

Sub_<identifier>

Befehlsblöcke definieren

WinBatch_<identifier>

Befehle, wie sie in Microsoft Windows Konsole eingegeben werden (Wichtig: Der Befehl muss als ausführbare Datei existieren!).

Files_<identifier>

Anweisungen zum Kopieren oder Löschen von Dateien

LinkFolder_<identifier>

Anweisungen um Verknüpfungen zu erstellen oder löschen

DosInAnIcon_<identifier>

In diese Sektionen kann ein komplettes Batch-Script geschrieben werden. Das Skript wird zur Laufzeit in eine Batchdatei geschrieben und dann ausgeführt.

Weitere Sektionen#

Der Zusatz „<identifier>“ wird immer durch eine Zeichenkette ersetzt, die die Aktion der Sektion beschreibt.

Sub_<identifier>#

Die Sub-Sektionen dienen der Zusammenfassung von Befehlsblöcken, um eine bessere Struktur zu bekommen.

Als Beispiel: Es wird überprüft, ob eine bestimmte Datei existiert und abhängig von dem Ergebnis eine Aktion ausgeführt.

[Aktionen]
Sub_Uninstall

[Sub_Uninstall]
if FileExists("Pfad zur Datei")
  WinBatch_Uninstall
endif

[WinBatch_Uninstall]
"Pfad zur Datei" /S

WinBatch_<identifier>#

In WinBatch-Sektionen kommen die Befehle, die unter Windows in der Konsole angegeben werden.

"%ScriptPath%dataSetup.exe" /S

Im Normalfall werden hier entweder die Setups, wie im oberen Beispiel aufgerufen oder man ruft den Microsoft Installer auf, wenn es sich um ein MSI-Paket handelt:

[WinBatch_<identifier>]
msiexec /passive /i "Pfad zu Msi-Datei"

Weitere Informationen zu den Aufrufen der verschiedenen Installationstypen finden Sie unter Unbeaufsichtigte Installationen.

Es ist wichtig, dass man überprüft, ob die Installation erfolgreich war oder nicht. Bei Aufrufen von WinBatch-Sektionen wird dies immer über den ExitCode gemacht. Die Sektion wird immer mit Sub_HandleExitCode bezeichnet und wird nach jedem Aufruf einer WinBatch-Sektion ausgeführt. Diese Sektion benötigt die Variable $ExitCode$.

Folgende Möglichkeiten stehen zur Verfügung:

beliebiger Installer (Installation und Deinstallation)

[Sub_HandleExitCode]
; check return code
Set $ExitCode$ = GetLastExitCode
comment "GetLastExitCode: " + $ExitCode$
if not($ExitCode$ = "0")
  LogError "Fatal: setup returned exit code " + $ExitCode$
  IsFatalError
endif

MSI-Installer

Installation:

[Sub_HandleExitCode]
; check return code
Set $ExitCode$ = GetLastExitCode
comment "GetLastExitCode: " + $ExitCode$
if not($ExitCode$ = "0" or $ExitCode$ = "3010")
  ; 0    ERROR_SUCCESS
  ; 3010 ERROR_SUCCESS_REBOOT_REQUIRED
  LogError "Fatal: setup returned exit code " + $ExitCode$
  IsFatalError
endif

Deinstallation:

[Sub_HandleExitCode]
; check return code
Set $ExitCode$ = GetLastExitCode
comment "GetLastExitCode: " + $ExitCode$
if not($ExitCode$ = "0" or $ExitCode$ = "1605" or $ExitCode$ = "3010")
  ; 0    ERROR_SUCCESS
  ; 1605 ERROR_UNKNOWN_PRODUCT
  ; 3010 ERROR_SUCCESS_REBOOT_REQUIRED
  LogError "Fatal: setup returned exit code " + $ExitCode$
  IsFatalError
endif

Sonderfälle bilden Frameworks, wie Adobe Air.

Files_<identifier>#

In Files-Sektionen kommen die Befehle, die unter Windows in der Konsole angegeben werden.

Im Beispiel werden alle Dateien im data-Verzeichnis auf die lokale Festplatte in das Verzeichnis C:tmp des Rechners kopiert.

[Files_<identifier>]
copy "%Scriptpath%\data\*" "%SystemDrive%\tmp"

Mögliche Befehl in dieser Sektion sind: copy und delete

Parameter

Funktion

-e (empty directories)

Kopiert auch leere Verzeichnisse

-f (force)

Erzwingt das Löschen der Dateien

-s (subdirectories)

Schließt alle Unterverzeichnisse ein

LinkFolder_<identifier>#

Mit den LinkFolder-Sektionen können Verknüpfungen angelegt oder gelöscht werden.

Dabei wird zunächst Verzeichnis, indem die Arbeiten durchgeführt werden sollen, mit set_basefolder "VERZEICHNIS" angegeben. Für „VERZEICHNIS“ können anstatt von absoluten Pfaden auch vordefinierte Variablen angeben werden. Danach muss angegeben werden, ob in einem Unterverzeichnis gearbeitet wird oder nicht. Mit set_subfolder "<UNTERVERZEICHNIS>" kann entweder das entsprechende Unterverzeichnis gewählt werden oder mit set_subfolder "" arbeitet man im aktuellen Verzeichnis.

Nun, da festgestellt ist, in welchen Verzeichnissen gearbeitet wird, können die eigentlichen Aktionen durchgeführt werden. Es gibt drei Möglichkeiten:

Verknüpfungen erstellen

set_link
  name: "<link name>"
  target: "<Pfad zur exe-Datei>"
end_link

Verknüpfungen löschen

delete_element "<link name>"

Unterverzeichnisse mit Verknüpfungen löschen

(Hierbei ist set_subfolder nicht notwendig.)

delete_subfolder "<folder path>"

Optionen für set_link

Parameter

Beschreibung

name

Titel der Verknüpfung

target

Pfad und Name der Zieldatei

parameters

eventuelle Kommandozeilenparameter, die übergeben werden müssen

working_dir

Arbeitsverzeichnis

icon_file

Pfad und Name des Icons; Standard = target

icon_index

Indexnummer des Icon in der Icon-Datei; Standard = 0

Hier ein Beispiel zum Anlegen einer Verknüpfung auf dem Desktop aller Benutzer:

[LinkFolder_Setup]
set_basefolder common_desktopdirectory
set_subfolder ""
set_link
  name: "Verknüpfung 1"
  target: "Pfad zur exe-Datei"
end_link

und ein Beispiel zum Löschen einer Verknüpfung aus dem Bereich „Alle Programme“ im Startmenü aller Benutzer:

[LinkFolder_Remove]
set_basefolder common_programs
set_subfolder "UNTERVERZEICHNIS"
delete_element "Verknüpfung"

Variablen und Konstanten#

Variablen werden in der Initial-Sektion definiert. Es handelt sich hierbei erstmal um leere Zeichenketten (Strings). OPSI kennt keine Variablentypen. Intern wird alles als String behandelt. Variablennamen werden immer mit $-Zeichen umschlossen. Konstant werden mit %-Zeichen umschlossen.

Zum Füllen von Variablen wird der Aufruf Set verwendet.

Set $Variable$ = "Wert"

Als Alternative ist noch der Aufruf SetConfidential vorhanden. Hierbei wird der Wert der Variable nur beim LogLevel 9 protokolliert. Andernfalls wird dieser durch den Ausdruck „(confidential)“ ersetzt. Dieser Aufruf ist besonders gut für die Verarbeitung von Seriennummern, Passwörter und anderen sensiblen Informationen geeignet

SetConfidential $Variable$ = "Geheimer Wert"

Befehle#

Die folgenden Befehle können in der Aktion-Sektion sowie in Sub-Sektionen verwendet werden.

Bedingungen#

OPSI kann Bedingungen abbilden. Als mögliche Operatoren stehen >=, >, =, <, <= zur Verfügung. Für die Invertierung eines Ausdrucks wird not(<Ausdruck>) verwendet.

if (1 >= 0)
  ; Mach was
else
  ; Mach was anderes
endif

OPSI kennt kein elseif. Falls man trotzdem in so eine Situation kommt, kann man im else-Teil einfach eine neue Abfrage starten.

Befehle#

Befehl

Beschreibung

GetMsVersionInfo

Gibt die NT-Kernelversion des aktuellen Rechners aus.

CompareDotSeparatedNumbers("<str1>", "<operator", "<str2>")

Vergleicht die Zahlen in den beiden Zeichenketten.

composeString("<stringlist>", "<glue>")

Setzt die Elemente der <stringlist> zu einem String zusammen. Als „Kleber“ wird <glue> verwendet.

splitString("<string>", "<separator>")

Konvertiert einen String in einer Stringlist, wobei der String an dem <separator> aufgeteilt wird.

GetSystemType

Liefert die aktuelle Architektur zurück

Beispiele

Aktuelle Windows-Version abfragen

Mit GetMsVersionInfo erhält man die aktuelle NT-Version.

 5.1  Windows XP
 6.0  Windows Vista
 6.1  Windows 7
 6.2  Windows 8
 6.3  Windows 8.1
10.0  Windows 10

Den abgerufenen Wert kann man nun mit der Funktion CompareDotSeparatedNumbers vergleichen.

Beispiel:

[Aktionen]
if (CompareDotSeparatedNumbers(GetMsVersionInfo, "6.1") = "0")
  ; Mach was speziell für Windows 7
endif

Aktuelle Architektur prüfen

GetSystemType liefert bei einer 64-Bit-Architektur den Wert 64 Bit System zurück. Wir prüfen also, ob dieser Wert zurück kommt, oder gehen von einer 32-Bit-Architektur aus.

if (GetSystemType = "64 Bit System")
    ; System ist 64-Bit
else
    ; System ist 32-Bit
endif

Falls man Ordner- oder Dateinamen hat, die die Architektur enthalten, kann man diesen oder einen anderen, passenden, Wert (x64, 64, …) in eine Variable speichern.

Eigenschaften auslesen

Die Werte aus den Paketeigenschaften werden mit der Funktion GetProductProperty ausgelesen. Der Wert sollte dabei direkt in eine Variable gespeichert werden. Der Aufbau des Befehls sieht dabei wie folgt aus

GetProductProperty("<PropertyName>", "<Standardwert>")

Beispiel:

[Initial]
DefVar $Seriennummer$

[Aktionen]
Set $Seriennummer$ = GetProductProperty("seriennummer", "")

Zeichen aus einem String entfernen

Als Beispiel: Microsoft Office möchte bei der Installation die Seriennummer ohne Bindestriche haben, daher verwenden die folgende Zeile, um die Bindestriche zu entfernen.

SetConfidential $ProductKey$ = composeString(splitString(GetProductProperty("productkey", ""), "-"), "")

Logging#

Mit dem Aufruf SetLogLevel wird die Stufe der Protokollierung festgelegt. Die folgende Auflistung stammt aus der offiziellen opsi-winst Dokumentation.

0 = nothing (absolute nothing)
1 = essential ("essential information")
2 = critical (unexpected errors that my cause a program abort)
3 = error (Errors that don't will abort the running program)
4 = warning (you should have a look at this)
5 = notice (Important statements to the program flow)
6 = info (Additional Infos)
7 = debug (important debug messages)
8 = debug2 (a lot more debug informations and data)
9 = confidential (passwords and other security relevant data)