14. Jan 2019
Lesedauer 26 Min.
MSI plus APPX gleich MSIX
Das Ende einer Ära
Ein Nachfolger für den austauschreifen Windows Installer steht bereits in den Startlöchern.

Es gab Zeiten, in denen das Thema der Softwareinstallation eine eher untergeordnete Rolle einnahm. Es gab keine Standardisierung, und jeder Softwarehersteller war gezwungen, eigene Installationsroutinen zu entwickeln und zu verwenden. Versionsüberprüfungen von Dateien waren in den Routinen enthalten, aber die finale Entscheidung über die durchzuführende Dateiaktion wurde auf den Anwender übertragen. Da es keine zentrale Überwachung der Installation gab, waren auch die Auswirkungen der Entscheidungen auf das Gesamtsystem nicht kalkulierbar. Der Benutzer konnte somit direkten Einfluss auf die Funktionsfähigkeit und Stabilität des Systems und der anderen Anwendungen ausüben.Der Windows Installer setzte erstmals das Betriebssystem in den Mittelpunkt des Installationsprozesses, indem die Durchführung und Kontrolle der Aktionen einem Betriebssystemdienst übertragen wurden. Der Benutzer wurde von schwer zu beantwortenden Fragen verschont, da der Installationsprozess durch fest verdrahtete und dokumentierte Regeln gesteuert wurde. Es wurde nahezu jede Aktivität protokolliert, sodass sie im Fehlerfall und auch während der Deinstallation problemlos rückgängig gemacht werden konnte. Die Problematik des DLL-Konflikts [1] konnte durch diese Regeln, Protokollierungen und sonstigen Implementierungen zwar gemildert, aber nicht gänzlich beseitigt werden.Dass der Windows Installer dennoch einen Meilenstein in der Installationsgeschichte darstellt, zeigt, dass erst nach fast 20 Jahren an seinem Thron gesägt wird – aber dass gesägt wird, lässt sich am Windows-Installer-Vorzeigeprodukt Microsoft Office deutlich erkennen. Die Version 2000 dieser Produkt-Suite war das erste Produkt, das den Windows Installer verwendete. Mehr noch, der Windows Installer wurde vom Office-Team entwickelt. Alle Office-Versionen nutzen seither den Windows Installer für den Installationsprozess. Seit Office 2010 wurde alternativ die Click-to-Run-Variante [2] eingesetzt. Mit Microsoft Office 2019 endet diese Beziehung endgültig; als Installationsprogramm wird nur noch die Click-to-Run-Variante verwendet, und der Abgesang auf den Windows Installer wird definitiv lauter.
Aufbruch in eine neue Zeit
Was alle bisherigen Installationslösungen gemeinsam haben, ist die individuell konfigurierbare und somit sehr flexible Ablagemöglichkeit der Anwendungsressourcen auf dem Zielsystem. Die hieraus resultierende unstrukturierte Speicherform in Verbindung mit der starken Verzahnung des Betriebssystems ist bei diversen Installationsaktionen irreversibel, sodass bei Deinstallationen immer Rückstände auf dem System verbleiben. Der Speicherbedarf des Systems steigt stetig an, die Performance sinkt und die Betriebssystemstabilität wird beeinträchtigt.In den Urzeiten des Setups war die Speicherung von Dateien im System- und Windows-Verzeichnis noch Usus. Mittlerweile wird hiervon konsequent Abstand genommen, wenngleich einige schwarze Schafe weiterhin existieren. Letztlich bleibt es aber dem Entwickler überlassen, die Speicherorte der Anwendungsressourcen festzulegen. Dies hat neben der sehr großen Ressourcenstreuung auch den unschönen Nebeneffekt, dass Ressourcen an zentralen Positionen sehr einfach überschrieben werden können und somit die Anwendungsstabilität nicht mehr gewährleistet ist. Die Frage nach der Notwendigkeit muss zwangsläufig gestellt werden.Smartphone-Apps als Vorbild
Dass es durchaus anders geht, zeigt der Siegeszug der Smartphones. Anwendungen, die hierbei erstmals als Apps bezeichnet wurden, werden in strukturierter Form auf das System gebracht. Der Ablageort ist festgelegt und geschützt, die Apps sind isoliert und Auswahlmöglichkeiten für den Benutzer sind erst gar nicht erforderlich. Im Ergebnis werden die Komplexität des Installationsprozesses und der Aufwand zur Erstellung von Installationsroutinen drastisch reduziert. Dies wirkt sich nicht nur positiv auf den Installationserfolg und die Installationsdauer der Apps aus, sondern ermöglicht auch effizientere Aktualisierungen des Betriebssystems. Die Deinstallation funktioniert ebenfalls zuverlässiger und zudem rückstandslos, da durch die vollständige Isolation der Apps lediglich das Löschen einer Ordnerstruktur nötig ist.Mit Windows 8 wurde erstmals ein Store für den Windows-PC bereitgestellt, aus dem sich die damals als Metro-Apps bezeichneten Anwendungen installieren ließen. Mit der Zeit wurde aus der Windows Runtime die Universal Windows Platform und aus den Metro-Apps wurden Modern Apps. Auch diese Bezeichnung wurde korrigiert, denn heutzutage werden sie schlicht als Store-Apps bezeichnet. Sie stellen mittlerweile den zweiten Anwendungstyp neben den klassischen Desktop-Anwendungen auf einem Windows-System dar. Als Installationsformat wurde das APPX-Paket entwickelt, das viele Probleme beseitigt, die bei klassischen Installationsformaten verbreitet waren. Es orientiert sich hierbei an den technischen Ansätzen, die bereits bei Smartphones zum Erfolg geführt haben.Der Erfolg blieb zunächst aus, denn die Nutzung der neuen Pakettechnologie erforderte die Nutzung der Universal Windows Platform als Entwicklungsparadigma. Dies bedeutete jedoch in der Konsequenz eine Neuentwicklung der bisherigen Desktop-Anwendungen. Viele Softwarehersteller scheuten diesen zusätzlichen Aufwand, sodass der Windows-Store in der Tat nur wenige und eher einfache Apps enthielt.Mit Projekt Centennial (Desktop Bridge) [3] wurde dieses Manko adressiert, indem es das Verpacken einer klassischen Desktop-Anwendung in ein APPX-Paket ohne Anpassung des Quellcodes ermöglicht. Neben einer strukturierten Speicherung der Ressourcen und einer rückstandsfreien Installation sind für diese Alt-Anwendungen nun auch automatische Updates über den Windows-Store möglich. Darüber hinaus ist ein solches APPX-Paket digital signiert und die Integrität der zu installierenden Ressourcen ist zwingend. Das Konzept scheint aufzugehen, denn nicht nur Microsoft wandelt die eigenen Alt-Anwendungen in Centennial-Apps um, sondern auch andere Softwarehersteller springen auf den Zug auf.Microsoft hat auf der Build 2018 eine neue Installationstechnologie mit der Bezeichnung MSIX vorgestellt, die alle bisherigen Installationstechnologien ersetzen soll. Auf der einen Seite wird durch die gewählte Bezeichnung die Nähe zum Windows Installer als State-of-the-Art-Installationsplattform hergestellt. Auf der anderen Seite werden durch das „X“ der Fortschritt und die neue Zeit betont. Als Dateiformat wird jetzt nicht mehr das binäre Compound Documentdes Windows Installer verwendet, sondern das moderne, auf ZIP und XML basierende OPC-Format (Open Packaging Conventions) [4]. Bei einer ersten Betrachtung fällt die Nähe zum APPX-Format deutlich auf und man ist geneigt, es lediglich als neue Bezeichnung, quasi als „APPX 2.0“, abzutun. Letztlich wurde aber mit Windows 10 Build 1809 das MSIX-Format nativ in das Betriebssystem integriert.Sinn oder Unsinn?
Die Frage nach der Notwendigkeit für ein neues Setup-Format ist unumstritten, denn mit Windows 10 wurde das Servicemodell radikal verändert. Der Lifecycle bei vorherigen Betriebssystemen betrug drei Jahre; bei Windows 10 erscheinen zweimal im Jahr neue Versionen. Bezogen auf das Firmenumfeld bedeutet dies einen erheblichen Aufwand, obgleich Microsoft die Strategie in der Form abgeschwächt hat, dass das Frühjahrs- und das Herbst-Update nicht mehr gleich relevant sein werden. Firmen werden vermutlich ihre Strategie dahingehend verändern, dass ein Betriebssystem-Update nur noch einmal pro Jahr ausgerollt wird. Wie bereits beschrieben sind die klassischen Desktop-Anwendungen stark mit dem Betriebssystem verzahnt und dort integriert. Eine Aktualisierung des Betriebssystems hat direkte Auswirkungen auf die Funktionsfähigkeit der entsprechenden Anwendung. Im Firmenumfeld müssen somit umfangreiche Tests mit den eingesetzten Anwendungen durchgeführt werden, die in vielen Fällen eine Paketierung oder Repaketierung der Software nach sich ziehen, wie es auch Bild 1 zeigt.
Darüber hinaus haben sich auch die Möglichkeiten zur Nutzung von Geräten im Firmenumfeld verändert. Wenngleich die Vielzahl der Geräte noch die On-Premises-Infrastruktur nutzt, nehmen alternative Nutzungsmodelle wie bei BYOD (Bring Your Own Device) zu. Solche Szenarien haben natürlich auch direkten Einfluss auf die Bereitstellung der Anwendungen. Installationen auf einem privaten Gerät stellen hierbei ganz andere technische Herausforderungen dar, da auf der einen Seite die klar definierten Systemvoraussetzungen der Firmenrechner nicht gegeben sind. Auf der anderen Seite können die Geräte nicht wie im Firmenumfeld eingeschränkt werden, da der Anwender weiterhin die Kontrolle über sein Gerät behalten möchte. Um diesen Faktoren entgegenzuwirken, wurden Virtualisierungs-Technologien wie App-V eingesetzt. Die hiermit gepackte Anwendung ist portabler, lässt sich in vielen Fällen ohne (Re-)Paketierung mit einem neuen Betriebssystem nutzen und kann zudem in BYOD-Szenarien effektiver verwendet werden.
Ab in den Container
Mit MSIX sind identische Lösungsansätze möglich, da die Ausführung der Anwendung innerhalb eines Containers erfolgt. Bei der Nutzung eines Containers wird keine virtuelle Maschine emuliert, sondern ein Layer dem Kernel des Betriebssystems vorgeschaltet, der die Aufrufe der Anwendungsschnittstellen abfängt und auf dieser Ebene virtualisiert. Die Nutzung der Containertechnologie ermöglicht die vollständige Trennung der auf einem Rechner genutzten Ressourcen, da alle Prozesse des Containers in einer geschützten Umgebung ausgeführt werden. Eine Anwendung oder ein Prozess, der in einem Container läuft, verwendet den Betriebssystem-Kernel und die Systemressourcen. Abhängig von der Art des Containers findet eine Isolierung zum Betriebssystem und zu anderen Containern statt, sodass sich die Anwendung so verhält, als ob sie in einer separaten Instanz des Betriebssystems ausgeführt würde. Container spielen bei Microsoft eine immer größere Rolle, da sie einen sehr leichtgewichtigen und daher flexiblen Virtualisierungsansatz verfolgen. Sie lassen sich einfach verteilen und migrieren und sind daher in Kompatibilitäts- und Sicherheitsszenarien unabdingbar. Es existieren unterschiedliche Anforderungen an die eingesetzten Container, sodass es verschiedene Containertechnologien gibt, die in Tabelle 1 gegenübergestellt werden. Die Microsoft-Codenamen hierfür lauten Helium, Argon, Krypton und Xenon.Tabelle 1: Container-Technologien in Windows
|
In Windows 10 ist beispielsweise die Sicherheitstechnologie Windows Defender Application Guard (WDAG) enthalten. Hiermit können Windows-10-Rechner wesentlich effektiver abgesichert werden, indem nicht vertrauenswürdige Webseiten isoliert werden. Wird über Microsoft Edge oder den Internet Explorer eine nicht vertrauenswürdige Website aufgerufen, wird die Website in einem isolierten Hyper-V-fähigen Container (Krypton) geöffnet, der vom Hostbetriebssystem vollständig getrennt ist. Der Host-PC ist aufgrund der Containerisolierung geschützt, und ein potenzieller Angreifer kann nicht auf die Unternehmensdaten zugreifen.Ein so abgesichertes System ist für die Vielzahl der Geschäftsanwendungen überdimensioniert. MSIX nutzt daher den Helium-Container zur Isolierung der Apps. Die Apps besitzen hierbei den vollen Zugriff auf Systemressourcen, verwenden aber ein virtuelles Dateisystem und virtualisierte Registrierungs-Einträge. Im Gegensatz zu einem Hyper-V-Container, zu denen Krypton und Xenon gehören, wird hierbei keine Sicherheitsgrenze zum Dateisystem und der Systemregistrierung gezogen.Zum besseren Verständnis: In einem MSIX-Paket befindet sich die Datei registry.dat. Hierbei handelt es sich um das logische Äquivalent zu HKEY_LOCAL_MACHINE\Software der realen Systemregistrierung. Zur Laufzeit werden die Inhalte dieser Struktur mit der realen Systemregistrierung dynamisch zusammengeführt, sodass nur eine Sicht für die Anwendung darauf besteht. Schreibzugriffe auf HKEY_LOCAL_MACHINE\Software sind möglich, sofern der korrespondierende Schlüssel oder Wert nicht im logischen Teil der Systemregistrierung existiert und der Benutzer über ausreichende Berechtigungen verfügt [5]. Somit ist nachvollziehbar, dass sich Änderungen durch die App auf den Host auswirken können; bei Krypton und Helium hingegen verbleibt alles im Container.Mit MSIX wurde die Container-Verwendung gegenüber APPX noch erweitert, wie das auch in Bild 2 zu sehen ist. Zunächst ist erkennbar, dass native Win32-Apps (Desktop-Apps) vollen Zugriff auf das System erhalten, ohne dass Mechanismen dies einschränken oder verhindern. Das Gegenteil davon bildet der stark abgesicherte und zuvor schon beschriebene WDAG-Container, der auf einem isolierten Kernel aufsetzt, wodurch Schadsoftware nicht das eigentliche System beeinflussen kann.
Zur Verwendung von „echten“ Universal Windows Apps existierte in der Zeit vor MSIX der bereits bekannte APPX-Container. Der Zugriff auf systemrelevante Ressourcen wird hierbei durch App-Funktionen (Capabilities) gesteuert. Seit Windows 10 Build 1607 ist es zudem möglich, native Win32-Anwendungen in ein Paket zu integrieren, das ebenfalls in einem Container ausgeführt wird. Dieser Desktop-Bridge-Container (Projekt Centennial) ermöglicht den Vollzugriff auf das System, wobei vorgeschaltete Filter für das Dateisystem und die Systemregistrierung diesen einschränken.Mit MSIX wurde die Trennung der zuvor genannten Container beseitigt und ein sehr flexibler MSIX-Container integriert. Hierbei handelt es sich ebenfalls um einen Helium-Container, der den Zugriff auf Systemfunktionen ermöglicht, aber durch die beschriebenen Filter und App-Funktionen eingeschränkt werden kann.
Exkurs: Windows-Installer-Paket
Der Windows Installer verwendet zum Speichern der Anwendungsdateien, Ressourcen und Installationsanweisungen das Compound-Document-Format. Dieses Format wurde ursprünglich für Office-Dokumente konzipiert, wie auch die Eigenschaftsbezeichnungen des Summary Information Stream [6] zeigen, der in jedem dieser Dokumente existiert. Da der Windows Installer vom Office-Entwicklerteam konzipiert wurde, ist die Verwendung dieses Formats naheliegend. Im Summary Information Stream sind neben allgemeinen Beschreibungen wie Titel, Autor und Kommentar auch installationsspezifische Daten zu finden. Bei der Betrachtung der Eigenschaftsbezeichnungen wird deutlich, dass dieses Format für Installationspakete zweckentfremdet wurde, denn Eigenschaften wie PID_PAGECOUNT oder PID_WORDCOUNT sind für Word-Dokumente hilfreich, aber für Installationspakete eher ungeeignet. Letztlich sollte man sich aber nicht von den Bezeichnungen leiten lassen, denn PID_PAGECOUNT enthält die mindestens erforderliche Version des Windows Installer für die Installation dieses Pakets. In PID_WORDCOUNT hingegen wird das Format festgelegt, in dem die zu installierenden Anwendungsdateien vorliegen sollen.Der Windows Installer unterstützt hierbei Ressourcen in komprimierter oder unkomprimierter Form. Bei unkomprimierter Verwendung befinden sich die Ressourcen in einer Ordnerstruktur und die MSI-Datei liegt in deren Stammverzeichnis. Bei der komprimierten Verwendung werden die Ressourcen in ein oder mehrere CAB-Dateien verpackt. Bei dieser Option kann weiterhin festgelegt werden, ob die CAB-Dateien in die MSI-Datei integriert werden oder ob sie außerhalb der Datei im Dateisystem abgelegt werden sollen.Die große Flexibilität beim Transport der Anwendungsdateien wird durch eine hohe Fehleranfälligkeit erkauft. Gerade bei der unkomprimierten Speicherung von Dateien kommt es immer wieder zu Installationsfehlern, da die maximale Pfadlänge überschritten wird und eine Fehlerkorrektur erforderlich wird. Darüber hinaus können bei dieser Speicheroption sehr einfach Anwendungsdateien ausgetauscht werden, da kein Manipulationsschutz existiert. Ohne großes Know-how kann somit Schadcode dem System zugefügt werden.Der Windows Installer bietet zwar die Möglichkeit, die zu installierenden Ressourcen über eine digitale Signatur zu schützen. Dies funktioniert jedoch nur für externe CAB-Dateien. Die Erfahrung zeigt allerdings, dass diese Methode eher selten genutzt wird und ein wirksamer Schutz deshalb nicht gegeben ist.Innerhalb des Installationspakets befindet sich eine relationale Datenbank. Diese enthält neben der Darstellung der Benutzeroberfläche auch Informationen zu der eigentlichen Installation. Windows Installer arbeitet nach einem deklarativen Ansatz, denn im Paket ist das Ergebnis der Installation beschrieben und nicht der Weg, wie er umgesetzt wird. Eine Ausnahme davon bilden die sogenannten benutzerdefinierten Aktionen. Hierunter verbirgt sich eine Implementierung zur Integration von Custom Code in den Installationsprozess.Zusammengefasst lässt sich feststellen, dass der Windows Installer eine sehr komplexe Technologie ist, die eine Vielzahl von Installations- und Konfigurationsoptionen zu bieten hat. Vieles davon ist dem Umstand geschuldet, dass sich die hiermit installierten Anwendungen tief in das System integrieren und die damit verbundenen Seiteneffekte und Auswirkungen auf andere Anwendungen wirkungsvoll reduziert werden können.Anatomie eines MSIX-Pakets
Beim MSIX-Format schließt sich der Kreis zum Entwicklerteam von Microsoft Office. Im Jahr 2006 schlug es in Zusammenarbeit mit anderen Microsoft-Gruppen einen neuen Standard namens Open Packaging Convention (OPC) vor, der als offener Standard veröffentlicht wurde [4]. Bei OPC handelt es sich nicht nur um ein Dateiformat, es ist zudem eine Containerdatei-Technologie, die über öffentliche Programmierschnittstellen wie System.IO.Packaging zugänglich gemacht wird.Auch wenn die Bezeichnung MSIX eine Nähe zum Windows Installer suggeriert, haben die beiden Technologien keine echten Gemeinsamkeiten. Bei MSIX gilt ganz klar: „Weniger ist mehr“, denn bei der Installation sollten immer die Klarheit des Prozesses, die Reduktion von potenziellen Fehlerquellen und die Funktionsfähigkeit der Anwendung im Vordergrund stehen. Die vielen Konfigurations- und Einstelloptionen des Windows Installer gibt es hierbei nicht, und auch Designs zur Darstellung von Benutzeroberflächen sucht man vergebens. Die Installation ist standardisiert und wird durch das Betriebssystem gesteuert und überwacht. Eine tiefe Integration der Anwendung in das System ist zudem auch gar nicht erforderlich.Das MSIX-Format ist daher weniger komplex und somit wesentlich einfacher zu verstehen. Letztlich handelt es sich bei einer MSIX-Datei um nichts anderes als eine ZIP-Datei, die ja bekanntlich jeder kennt. Darüber hinaus wurden beim Design von MSIX die erwähnten Problempunkte des Windows-Installer-Formats beseitigt:- Alles, was für die Installation benötigt wird, findet sich nun in einer einzigen Datei.
- Die deklarative Installation wird über eine Manifestdatei (XML) beschrieben und nicht mittels einer relationalen Datenbank.
- Sicherheit ist nicht mehr optional, sondern zwingend. Das Paket muss signiert und die Signatur muss auf dem Gerät als vertrauenswürdig definiert werden. Darüber hinaus existiert ein wirkungsvoller Manipulationsschutz für das Paket.
- Das Betriebssystem verwaltet die Installation, Aktualisierung und Entfernung, und da die Verwendung von Custom Code nicht möglich ist, ist das Ergebnis nachvollziehbar.
Der Inhalt der Datei lässt sich in die beiden Kategorien Package Payload und Footprint Files unterteilen, wie das auch der Vergleich mit einem Windows-Installer-Paket in Bild 4 zeigt. Payload lässt sich mit dem Begriff Nutzlast übersetzen, und dies trifft die Bestimmung ganz gut. Hierbei handelt es sich letztlich um die Ressourcen, die für die Funktionsfähigkeit der App und die Darstellung im System erforderlich sind. Also die Dateien, die bei der Erstellung des Pakets individuell festgelegt werden, wie etwa die Anwendungsdateien und die Bild-Ressourcen zur Darstellung auf der Kachel und an weiteren Orten im System.
Zur Nutzung der Ressourcen muss ein Index aller Varianten erstellt und als Datei in das Paket integriert werden [7]. Hierbei handelt es sich um den sogenannten Package Resource Index oder kurz PRI.Ein Paket enthält normalerweise pro Sprache eine einzelne PRI-Datei mit der Bezeichnung resources.pri. Zur Laufzeit erkennt das System die momentan geltenden Benutzer- und Computereinstellungen, fragt die Informationen in der PRI-Datei ab und lädt automatisch die Ressourcen, die für diese Einstellungen am besten geeignet sind.Beim Erstellen einer Universal App mit Visual Studio 2017 wird der Package Resource Index automatisch erzeugt. Die dafür verwendete Befehlszeile lässt sich im Ausgabefenster von Visual Studio ermitteln, sofern unter Tools | Options | Projects and Solutions | Build and Run mindestens die Standardausgabe der Build-Ereignisse konfiguriert wurde.Ist die Datei resources.pri nicht vorhanden oder haben sich die Ressourcen verändert, so muss die Datei neu erstellt werden. Hierfür steht neben Visual Studio 2017 auch die Anwendung makepri.exe des Windows SDK zur Verfügung. Zur Erstellung muss zunächst eine Konfigurationsdatei erzeugt werden. Anschließend ist die Generierung der PRI-Datei möglich.
d:\msixapp>makepri<span class="hljs-selector-class">.exe</span> createconfig /cf
d:\resources<span class="hljs-selector-class">.pri</span><span class="hljs-selector-class">.xml</span> /dq en-us /pv <span class="hljs-number">10.0</span>.<span class="hljs-number">0</span>
d:\msixapp>makepri<span class="hljs-selector-class">.exe</span> new /pr d:\msixapp /cf
d:\resources<span class="hljs-selector-class">.pri</span><span class="hljs-selector-class">.xml</span>
Es ist darauf zu achten, dass die Ausführung der Befehle aus dem Stammordner des Pakets, in diesem Fall d:\msixapp, erfolgt. Die erstellte Datei resources.pri ist im Binärformat gespeichert. Um die Inhalte zu betrachten, kann ein Dump in einer Datei persistiert werden.
d:\>makepri<span class="hljs-selector-class">.exe</span> dump /<span class="hljs-keyword">if</span> d:\msixapp\resources<span class="hljs-selector-class">.pri</span>
Das in Bild 3 dargestellte Beispiel ist sehr übersichtlich strukturiert. Nahezu alle Payload Files finden sich in den Unterordnern VFS und Assets.Das Layout ist jedoch nicht standardisiert. Die Payload Files können sich auch im Stammverzeichnis befinden, wie in dem Beispiel die Dateien der virtuellen Systemregistrierung Registry.dat, User.dat und UserClasses.dat. Entscheidend ist letztlich die richtige Referenzierung der ausführbaren Datei in der Datei AppxManifest.xml. Selbstverständlich muss das Layout auch so gewählt werden, dass die Funktionalität aus Anwendungssicht sichergestellt ist.Um den OPC zu entsprechen, müssen alle Datei- und Verzeichnisnamen innerhalb des MSIX-Pakets als Uniform Resource Identifier (URI) bezeichnet werden. Bezeichnungen, die nicht URI-kompatibel sind, müssen im Paket entsprechend codiert und beim Extrahieren wieder decodiert werden. Alle Anwendungen, die zum Erstellen und Entpacken das Packaging-API [8] verwenden, kümmern sich automatisch um die Codierung und Decodierung der Bezeichnungen. Bei der Verwendung von generischen Anwendungen zur Bearbeitung von ZIP-Dateien ist das nicht der Fall, sodass hier manuell nachgebessert werden muss.Bei den Footprint Files ist eine individuelle Namensvergabe nicht möglich. Die folgenden Datei- und Ordnerbezeichnungen sind hierfür reserviert und dürfen daher auch nicht für Payload Files verwendet werden:
- ./[Content_Types].xml:Metadaten für Inhaltstypen, die von OPC benötigt werden
- ./AppxManifest.xml: Anwendungsmanifestdatei des Pakets
- ./AppxBlockMap.xml: Blockmap-Datei des Pakets
- ./AppxSignature.p7x: Digitale Signatur des Pakets
- ./AppxMetadata/: Ordner für Metadateien
- ./AppxMetadata/CodeIntegrity.cat: Signierte Katalogdatei zur Sicherstellung der Codeintegrität
Listing 1: Manifestdatei für ein MSIX-Paket
<span class="php"><span class="hljs-meta">&lt;?</span>xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span><span class="hljs-meta">?&gt;</span></span> <br/><span class="hljs-tag">&lt;<span class="hljs-name">Package</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> manifest/foundation/windows10"</span> <span class="hljs-attr">xmlns:uap</span>=<span class="hljs-string">"http://</span></span><br/><span class="hljs-tag"><span class="hljs-string"> schemas.microsoft.com/appx/manifest/uap/windows10"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">xmlns:uap2</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> manifest/uap/windows10/2"</span> <span class="hljs-attr">xmlns:uap3</span>=<span class="hljs-string">"http://</span></span><br/><span class="hljs-tag"><span class="hljs-string"> schemas.microsoft.com/appx/manifest/uap/windows10/3"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">xmlns:uap4</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> manifest/uap/windows10/4"</span> <span class="hljs-attr">xmlns:uap6</span>=<span class="hljs-string">"http://</span></span><br/><span class="hljs-tag"><span class="hljs-string"> schemas.microsoft.com/appx/manifest/uap/windows10/6"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">xmlns:uap7</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> manifest/uap/windows10/7"</span> <span class="hljs-attr">xmlns:mobile</span>=<span class="hljs-string">"http://</span></span><br/><span class="hljs-tag"><span class="hljs-string"> schemas.microsoft.com/appx/manifest/mobile/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> windows10"</span> <span class="hljs-attr">xmlns:iot</span>=<span class="hljs-string">"http://schemas.microsoft.com/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> appx/manifest/iot/windows10"</span> <span class="hljs-attr">xmlns:desktop</span>=<span class="hljs-string">"http://</span></span><br/><span class="hljs-tag"><span class="hljs-string"> schemas.microsoft.com/appx/manifest/desktop/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> windows10"</span> <span class="hljs-attr">xmlns:desktop2</span>=<span class="hljs-string">"http://schemas.microsoft.</span></span><br/><span class="hljs-tag"><span class="hljs-string"> com/appx/manifest/desktop/windows10/2"</span> <span class="hljs-attr">xmlns:rescap</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"http://schemas.microsoft.com/appx/manifest/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> foundation/windows10/restrictedcapabilities"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">xmlns:rescap3</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> manifest/foundation/windows10/restrictedcapabilities </span></span><br/><span class="hljs-tag"><span class="hljs-string"> /3"</span> <span class="hljs-attr">xmlns:com</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/</span></span><br/><span class="hljs-tag"><span class="hljs-string"> manifest/com/windows10"</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Identity</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"NativeNotepad"</span> <span class="hljs-attr">Publisher</span>=<span class="hljs-string">"CN=AK"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">Version</span>=<span class="hljs-string">"1.0.0.0"</span> <span class="hljs-attr">ProcessorArchitecture</span>=<span class="hljs-string">"x64"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Properties</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">DisplayName</span>&gt;</span>Native Notepad<span class="hljs-tag">&lt;/<span class="hljs-name">DisplayName</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">PublisherDisplayName</span>&gt;</span>Andreas Kerl<br/> <span class="hljs-tag">&lt;/<span class="hljs-name">PublisherDisplayName</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Description</span>&gt;</span>Reserved<span class="hljs-tag">&lt;/<span class="hljs-name">Description</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Logo</span>&gt;</span>Assets\StoreLogo.png<span class="hljs-tag">&lt;/<span class="hljs-name">Logo</span>&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">Properties</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Resources</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Resource</span> <span class="hljs-attr">Language</span>=<span class="hljs-string">"en-us"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">Resources</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Dependencies</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">TargetDeviceFamily</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"Windows.Desktop"</span> </span><br/><span class="hljs-tag"> <span class="hljs-attr">MinVersion</span>=<span class="hljs-string">"10.0.14936.0"</span> <span class="hljs-attr">MaxVersionTested</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"12.0.0.0"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">Dependencies</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Capabilities</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">rescap:Capability</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"runFullTrust"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">Capabilities</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Applications</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">Application</span> <span class="hljs-attr">Id</span>=<span class="hljs-string">"NATIVENOTEPAD"</span> <span class="hljs-attr">Executable</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"NativeNotepad.exe"</span> <span class="hljs-attr">EntryPoint</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"Windows.FullTrustApplication"</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">uap:VisualElements</span> <span class="hljs-attr">BackgroundColor</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"transparent"</span> <span class="hljs-attr">DisplayName</span>=<span class="hljs-string">"Native Notepad </span></span><br/><span class="hljs-tag"><span class="hljs-string"> 1.0"</span> <span class="hljs-attr">Square150x150Logo</span>=<span class="hljs-string">"Assets\Square150x</span></span><br/><span class="hljs-tag"><span class="hljs-string"> 150Logo.png"</span> <span class="hljs-attr">Square44x44Logo</span>=<span class="hljs-string">"Assets\</span></span><br/><span class="hljs-tag"><span class="hljs-string"> Square44x44Logo.png"</span> <span class="hljs-attr">Description</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"Native Notepad 1.0"</span>&gt;</span> <br/> <span class="hljs-tag">&lt;<span class="hljs-name">uap:DefaultTile</span> <span class="hljs-attr">Wide310x150Logo</span>=<span class="hljs-string">"Assets\</span></span><br/><span class="hljs-tag"><span class="hljs-string"> Wide310x150Logo.png"</span> <span class="hljs-attr">Square310x310Logo</span>=</span><br/><span class="hljs-tag"> <span class="hljs-string">"Assets\Square310x310Logo.png"</span> <span class="hljs-attr">Square71x71</span></span><br/><span class="hljs-tag"> <span class="hljs-attr">Logo</span>=<span class="hljs-string">"Assets\Square71x71Logo.png"</span> /&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">uap:VisualElements</span>&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">Application</span>&gt;</span> <br/> <span class="hljs-tag">&lt;/<span class="hljs-name">Applications</span>&gt;</span> <br/><span class="hljs-tag">&lt;/<span class="hljs-name">Package</span>&gt;</span>
Der Aufbau und der Inhalt der Manifestdatei entsprechen denen eines APPX-Pakets. Lediglich im Bereich der Schemadefinitionen hat sich etwas getan, denn diese wurden um neue Definitionen ergänzt [9]. Im Element <Identity/> werden wie bekannt die Identifizierungsmerkmale der App festgelegt, die auch in Aktualisierungsszenarien entscheidend sind. Mithilfe der <Properties/> werden Informationen zur Darstellung des MSIX-Pakets auf dem System angegeben, und in den <Dependencies/> werden die erforderlichen Abhängigkeiten definiert. Der Unterordner Assets enthält die zu nutzenden Bilddateien, die an unterschiedlichen Positionen im Manifest referenziert und benutzt werden. Die Applications-Auflistung enthält das Element zur Festlegung der ausführbaren Datei, und über die Capabilities-Auflistung werden Ausführungsberechtigungen vergeben. In diesem Beispiel befindet sich die ausführbare Datei NativeNotepad.exe im gleichen Verzeichnis wie die Manifestdatei.Wie zuvor bereits erwähnt werden Apps in einem Container ausgeführt. Das Betriebssystem enthält einen integrierten Client, mit dem die Bereitstellung, Konfiguration und Ausführung des Containers gesteuert wird. Bei Bedarf kann jeder Container individuell konfiguriert werden, wobei Windows den Überblick und die Kontrolle über die Inhalte behält.Dies ist nicht neu, denn APPX funktioniert auf identische Weise. MSIX ermöglicht jedoch eine wesentlich größere Flexibilität bei der Nutzung und Konfiguration des Containers. So kann ein Container einfache Mechanismen wie die bereits erwähnten Dateisystem- und Systemregistrierungsfilter von Projekt Centennial nutzen, aber auch komplexere Szenarien wie das Capability-Modell der Universal Windows Apps. Dies hat den Vorteil, dass Berechtigungen beispielsweise für das Adressbuch auf Ebene der Apps erteilt werden können. Die Konfiguration des Containers erfolgt innerhalb der Datei AppxManifest.xml.Bei Win32-Anwendungen besteht mitunter die Notwendigkeit, diese mit erhöhten Privilegien auszuführen. Wurde im Anwendungsmanifest (app.manifest) der Ausführungslevel wie folgt definiert, schlägt die Ausführung der App fehl, falls sie nicht mit Administratorrechten ausgeführt wurde:
<span class="hljs-tag"><<span class="hljs-name">requestedExecutionLevel</span> <span class="hljs-attr">level</span>=<span class="hljs-string">"requireAdministrator"</span> </span>
<span class="hljs-tag"> <span class="hljs-attr">uiAccess</span>=<span class="hljs-string">"false"</span> /></span>
Mit MSIX und Windows 10 Build 1809 ist es möglich, eine automatische Heraufstufung beim Starten der App zu veranlassen. Hierzu ist das Element <Capability/> um allowElevation zu erweitern:
<span class="hljs-tag"><<span class="hljs-name">Capabilities</span>></span>
<span class="hljs-tag"><<span class="hljs-name">rescap:Capability</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"runFullTrust"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name">rescap:Capability</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"allowElevation"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">Capabilities</span>></span>
Zur Erstellung von MSIX-Paketen existieren aktuell makeappx.exe, Visual Studio 2017 Version 15.9 und das MSIX Packaging Tool [10]. Letzteres erfordert zwingend Windows 10 Build 1809 oder höher. Zur Erstellung von MSIX-Paketen mit makeappx.exe muss mindestens Windows 10 SDK Preview Build 17682 vorhanden seinDie folgenden Kapazitätsgrenzen sind bei der Erstellung zu beachten, wobei eine Überschreitung eher theoretischer Natur ist:
- Maximale Größe einer MSIX-Datei: 100 Gigabyte
- Maximale Anzahl der enthaltenen Dateien: 100 000
makeappx<span class="hljs-selector-class">.exe</span> pack /d D:\MSIX\Source /<span class="hljs-selector-tag">p</span>
D:\MSIX\Source\MSIXDemo_1.<span class="hljs-number">0.0</span>.<span class="hljs-number">0</span><span class="hljs-selector-class">.msix</span>
Beim Erstellvorgang werden Metainformationen ins Paket geschrieben, damit Unterschiede zwischen verschiedenen Versionen des Pakets genau identifiziert werden können. Dies ist in Aktualisierungsszenarien erforderlich, um nur die geänderten Teile zweier Pakete inkrementell laden und anwenden zu können, um somit differentielle Block-Updates auf Anwendungsebene zu realisieren.Die Metainformationen sind in der Datei AppxBlockMap.xml enthalten. Sie wird automatisch erstellt und enthält eine zweidimensionale Liste mit Informationen zu den im Paket enthaltenen Dateien. Die erste Dimension enthält generische Informationen zum Namen und zur Größe der Datei. Die zweite Dimension enthält einen SHA256-Hash für jeden 64-KB-Block der Datei, wie auch nachfolgend ersichtlich ist:
<span class="php"><span class="hljs-meta"><?</span>xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"UTF-8"</span> standalone=<span class="hljs-string">"no"</span><span class="hljs-meta">?></span></span>
<span class="hljs-tag"><<span class="hljs-name">BlockMap</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://schemas.microsoft.com/appx/2010/</span></span>
<span class="hljs-tag"><span class="hljs-string"> blockmap"</span> <span class="hljs-attr">HashMethod</span>=<span class="hljs-string">"http://www.w3.org/2001/04/</span></span>
<span class="hljs-tag"><span class="hljs-string"> xmlenc#sha256"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">File</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"NativeNotepad.exe"</span> <span class="hljs-attr">Size</span>=<span class="hljs-string">"112640"</span> </span>
<span class="hljs-tag"> <span class="hljs-attr">LfhSize</span>=<span class="hljs-string">"47"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">Block</span> <span class="hljs-attr">Hash</span>=<span class="hljs-string">"RKGiMxrpgKj4WsD55NgeT2os7rC4rnGFqUN</span></span>
<span class="hljs-tag"><span class="hljs-string"> icePIvuY="</span> <span class="hljs-attr">Size</span>=<span class="hljs-string">"24857"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name">Block</span> <span class="hljs-attr">Hash</span>=<span class="hljs-string">"b0ofrgmL2CCL5m3ZInQp4URNJSzYLkBNzpi</span></span>
<span class="hljs-tag"><span class="hljs-string"> CsA5Wt4M="</span> <span class="hljs-attr">Size</span>=<span class="hljs-string">"5288"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name">File</span>></span>
<span class="hljs-tag"><<span class="hljs-name">File</span> <span class="hljs-attr">Name</span>=<span class="hljs-string">"AppxManifest.xml"</span> <span class="hljs-attr">Size</span>=<span class="hljs-string">"2302"</span> </span>
<span class="hljs-tag"> <span class="hljs-attr">LfhSize</span>=<span class="hljs-string">"46"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">Block</span> <span class="hljs-attr">Hash</span>=<span class="hljs-string">"2Ry+CyLTAshtcy7ipOLhX+DpAf+AENq9h4L</span></span>
<span class="hljs-tag"><span class="hljs-string"> xbzIbaPA="</span> <span class="hljs-attr">Size</span>=<span class="hljs-string">"729"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name">File</span>></span>
<span class="hljs-tag"></<span class="hljs-name">BlockMap</span>></span>
Die erste Datei NativeNotepad.exe hat eine Größe von 110 KB und wird daher durch zwei Hash-Blöcke dargestellt. Der erste Hash repräsentiert den ersten 64-KB-Block der Datei, und der zweite Hash repräsentiert die restlichen 46 KB. Beim Einspielen eines Aktualisierungspakets werden die Hashwerte der einzelnen Blöcke miteinander verglichen. Die Download-Komponente lädt nur die veränderten Blöcke und nutzt die unveränderten Blöcke aus dem bereits installierten Paket. Gerade in größeren Paketen, in denen wenige Änderungen durchgeführt wurden, werden hierdurch Zeit und Ressourcen eingespart.Das so erstellte Paket lässt sich aber noch nicht verwenden, da es zuvor noch digital signiert werden muss.
<span class="hljs-selector-tag">signtool</span><span class="hljs-selector-class">.exe</span> <span class="hljs-selector-tag">sign</span> <span class="hljs-selector-tag">-f</span> <span class="hljs-selector-tag">D</span>:\<span class="hljs-selector-tag">Cert</span>\<span class="hljs-selector-tag">ak</span><span class="hljs-selector-class">.pfx</span> <span class="hljs-selector-tag">-fd</span> <span class="hljs-selector-tag">SHA256</span> <span class="hljs-selector-tag">-v</span>
<span class="hljs-selector-tag">D</span>:\<span class="hljs-selector-tag">MSIX</span>\<span class="hljs-selector-tag">Source</span>\<span class="hljs-selector-tag">MSIXDemo_1</span><span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.msix</span>
Hierbei ist zu beachten, dass das Attribut Publisher des Elements <Identity/> der Datei AppxManifest.xml mit dem Subject-Element des Codesignaturzertifikats übereinstimmen muss. Im Weiteren muss der Hash-Algorithmus zum Signieren des Pakets mit dem Hash-Algorithmus übereinstimmen, der zum Erstellen der AppxBlockMap.xml verwendet wurde. Dieser ist im Attribut HashMethod des Elements <BlockMap/> zu finden.Beim Signieren wird nicht nur eine digitale Signatur auf das erstellte MSIX-Paket aufgebracht, sondern auch ein wirksamer Manipulationsschutz integriert. Es gehört zum guten Ton, dass ausführbare Dateien ebenfalls mit einer Signatur zu versehen sind. Die Zuständigkeit für die Signierung von Dateien liegt beim Erzeuger der Datei, sodass im Rahmen der Paketerzeugung die Anwendungsdateien nicht betrachtet werden.Die Datei AppxBlockMap.xml ist für die Funktionalität und Integrität des MSIX-Pakets ganz wesentlich, sodass hierfür ein Manipulationsschutz erforderlich ist. Es lassen sich jedoch nur Dateien mit einem PE-Header (.exe, .dll et cetera) und spezielle Archivdateien (.cab, .msix, .appx, .msibundle, .pfx et cetera) digital signieren. Aus diesem Grund wird beim Signieren eine PFX-Datei (PKCS #12) erstellt und unter der Bezeichnung AppxSignature.p7x gespeichert. Hierbei handelt es sich um eine Archivdatei zum Speichern diverser Kryptografieobjekte. Eine solche Datei enthält interne Speicherbehälter, die wie die Datei verschlüsselt und signiert sein können. In diesen Speicherbehältern können Zertifikate, private Schlüssel, Zertifikatssperrlisten und individuelle Daten abgelegt werden. Um einen wirkungsvollen Manipulationsschutz für Teile des MSIX-Pakets zu erlangen, die nicht direkt signiert werden können, werden die nachfolgenden Hashes ermittelt und in die Datei AppxSignature.p7x übertragen.
- Package Block Map: Hash der Datei AppxBlockMap.xml
- Package Content: Hash über alle Dateien des Pakets mit Ausnahme der Datei AppxBlockMap.xml
- Package Directory: Hash über das zentrale Verzeichnis der ZIP-Datei. Dieses befindet sich am Dateiende und enthält Referenzen auf die enthaltenen Dateien.
- Identifikation des Urhebers der Unterschrift
- Sicherstellung, dass der signierte Inhalt nicht verändert wurde
Enterprise-Funktionalität
Eine der wichtigsten Zielsetzungen des Windows Installer war die effektive Integration eines Installationssystems in das Unternehmensumfeld. Hierunter fallen nicht nur die Stabilitäts- und Transaktionsmechanismen, sondern vielmehr die Enterprise-Funktionalität im Paketierungsumfeld der IT-Professionals.In der Vergangenheit hat Microsoft es leider versäumt, diese für das Unternehmensumfeld absolut notwendigen Implementierungen auf modernere Installationstechnologien auszuweiten. Mit MSIX wird hier nachgebessert, denn einfach ausgedrückt wird hiermit APPX um Enterprise-Funktionen erweitert, die darüber hinaus noch einiges mehr zu bieten haben als die des Windows Installer. Dies ist absolut notwendig, denn die im Unternehmensumfeld eingesetzten Softwarepakete müssen in den meisten Fällen angepasst werden, damit sie in der erforderlichen Konfiguration automatisiert verteilt werden können und dem Firmen-Branding entsprechend im System erscheinen.Steht der Quellcode der Anwendung zur Verfügung, können die Anforderungen direkt implementiert werden. Handelt es sich jedoch um Third-Party-Software, lässt sich ein solcher Anpassungslevel nicht realisieren, denn Firmen wie Microsoft oder Adobe können keine individuellen Versionen ihrer Software für jede nutzende Firma bereitstellen. Zur Umsetzung der erforderlichen Konfigurationen bleibt somit nichts anderes übrig, als das bereitgestellte Installationspaket anzupassen, indem in letzter Konsequenz eine Repaketierung durchgeführt wird.Dies ist jedoch kein einmaliger Prozess, denn beim Erscheinen jedes neuen Softwarereleases ist der aufwendige und somit kostenintensive Konfigurations- und Repaketierungsprozess erneut zu durchlaufen, und ein neues Installationspaket muss auf Basis des Originals erstellt werden, wie auch Bild 6 verdeutlicht.
Gerade in Zeiten agiler Softwareentwicklungsprozesse werden die Zyklen zur Bereitstellung neuer Softwareversionen immer kürzer. Durch neue Versionen des Betriebssystems, die Bereitstellung neuer Sicherheitsupdates oder neue Funktionsanforderungen an die Anwendung ist die Notwendigkeit zur schnellen Bereitstellung neuer Softwareversionen unabdingbar. Der hohe Aufwand bei der Konfiguration und Repaketierung im Unternehmensumfeld macht es hingegen unmöglich, wichtige oder kritische Updates schnellstmöglich bereitzustellen. Die IT-Pros können das Entwicklungstempo nicht mehr mitgehen, sodass Einbußen bei der Qualität, Funktionalität und Sicherheit der eingesetzten Software in Kauf genommen werden müssen.MSIX löst dieses Problem durch Entkoppelung der Anwendung von der Konfiguration, indem hierfür unterschiedliche MSIX-Pakete verwendet werden. Es ist dadurch nicht mehr erforderlich, bei jeder neuen oder geänderten Anwendung den vollständigen Paketierungsprozess zu durchlaufen. Das unveränderte Herstellerpaket kann direkt verwendet werden. Das für die Vorversion erstellte Modifikationspaket kann ebenfalls weiterverwendet werden, solange keine Änderungen in der Hauptanwendung vorgenommen wurden, die sich auf die vorgenommenen Konfigurationsanpassungen auswirken (Breaking Changes).Beim Modifikationspaket handelt es sich um ein spezielles MSIX-Paket, das eine Abhängigkeit zum Hauptpaket aufweist. Dies wird auch in den Windows-Einstellungen verdeutlicht: Unter Apps & Features wird lediglich das Hauptpaket angezeigt. Das Modifikationspaket kann verwaltet werden, wenn für die entsprechende App der Punkt Erweiterte Optionen aufgerufen wird. Hier erscheint das Modifikationspaket unter App-Add-Ons und herunterladbare Inhalte, wie das auch Bild 7 zeigt.
Ein Blick unter die Haube zeigt interessante Details zu dieser Funktionalität. Im Beispiel wird die Anwendung NativeNotepad auf dem System installiert. Die ausführbare Datei befindet sich im Ordner %ProgramFiles%\NativeNotepad, wie das auch der Blick in das virtuelle Dateisystem aus dem bereits bekannten Bild 3 zeigt. Durch das Modifikationspaket wird eine Textdatei mit der Bezeichnung help.txt in dieses Verzeichnis kopiert und zusätzlich ein Systemregistrierungseintrag unter HKEY_LOCAL_MACHINE erstellt. Die Anwendung ist so konzipiert, dass die Textdatei automatisch geladen wird, sofern sie vorhanden ist, und der Registrierungseintrag die Hintergrundfarbe des Textfelds verändert.Nachdem das Haupt- und das Modifikationspaket installiert wurden, lässt sich die erfolgreiche Verwendung der Modifikation direkt nachvollziehen. Darüber hinaus können die vollständige Isolation und Unabhängigkeit der beiden Pakete dargestellt werden. Durch Aufruf des PowerShell-Befehls Get-AppxPackage werden zunächst alle auf der Maschine installierten Pakete nach Installationsdatum sortiert angezeigt.Wie in Bild 8 erkennbar, wird das Hauptpaket am Ende der Liste angezeigt, und in den Dependencies wird auf das Modifikationspaket verwiesen.
Zur weiteren Analyse wird das Anwendungsverzeichnis betrachtet, das sich im virtuellen Dateisystem des Hauptpakets unter folgendem Pfad befindet:
<span class="hljs-variable">%ProgramFiles%</span><span class="hljs-symbol">\W</span>indowsApps<span class="hljs-symbol">\N</span>ativeNotepad_1.0.0.0_x64__yf
5adtgdrdj2a<span class="hljs-symbol">\V</span>FS<span class="hljs-symbol">\P</span>rogramFilesX64<span class="hljs-symbol">\N</span>ativeNotepad.
In diesem Verzeichnis finden sich tatsächlich nur die Dateien NativeNotepad.exe und Readme.txt aus dem Hauptpaket. Zur Betrachtung des virtuellen Dateisystems des Modifikationspakets ist der vollständige Paketname aus den Dependencies dem Ordner %ProgramFiles%\WindowsApps anzufügen. In diesem Anwendungsverzeichnis findet sich hingegen die neu hinzugefügte Textdatei help.txt, sodass hiermit die physische Trennung der Pakete bewiesen ist, wie das auch Bild 9 zeigt.
Innerhalb der Anwendung wird der Dateipfad mit dem folgenden Befehl ermittelt und die Datei geladen:
string file = <span class="hljs-keyword">Path</span>.Combine(<span class="hljs-keyword">Environment</span>.
GetFolderPath(<span class="hljs-keyword">Environment</span>.SpecialFolder.
ProgramFiles), @<span class="hljs-string">"NativeNotepad\Help.txt"</span>);
Das Ganze ist möglich, da Windows die virtuellen Dateisysteme des Hauptpakets und des Modifikationspakets zusammenführt. Die Suche nach der Datei erstreckt sich daher nicht nur auf das virtuelle Dateisystem des Hauptpakets. Sie wird auch auf alle Modifikationspakete ausgedehnt. Interessant ist dieser Sachverhalt auch in Update-Szenarien. Wird ein Aktualisierungspaket für die Hauptanwendung installiert, bleibt das Modifikationspaket erhalten und die Anwendung funktioniert weiterhin wie gerade beschrieben.Diese vollständige Trennung zwischen Haupt- und Modifikationspaket ist ein Riesenschritt im Vergleich zum Windows Installer. Hier war es zwar ebenfalls möglich, Konfigurationsdateien per Patch (.msp), Transformation (.mst) oder als ein separates Paket (.msi) bereitzustellen. Allerdings wurden die Dateien hierbei physisch in das Installationsverzeichnis des Hauptverzeichnisses integriert, sodass eine Isolation oder Unabhängigkeit der Pakete nicht gegeben war.Die Installation eines Modifikationspakets wird auf einem System ohne installiertes Hauptpaket mit einer Fehlermeldung und einem Installationsabbruch quittiert. Das Modifikationspaket kann somit nicht als eigenständiges Programm installiert werden und wird daher auch mit dem Hauptpaket zusammen deinstalliert. Sobald es jedoch bereitgestellt ist, kann die enthaltene Konfiguration durch die Hauptanwendung genauso verwendet werden, als wenn sie Bestandteil davon wäre. Die Installation kann wie bei den Hauptpaketen mit den Werkzeugen des Betriebssystems erfolgen:
- App-Installer: Wird durch einen Doppelklick auf die Datei oder durch den Befehl ms-appinstaller:?source=<URI> aufgerufen. Es wird immer eine Benutzeroberfläche angezeigt.
- PowerShell: Eignet sich, um eine Installation ohne Benutzeroberfläche durchzuführen. Der Befehl Add-AppxPackage kann auch für MSIX-Pakete genutzt werden. Es ist zu vermuten, dass in späteren Windows-Versionen die PowerShell-Cmdlets noch umbenannt werden.
- Store oder Business-Store: Analog zum App-Installer: Die App wird im jeweiligen Store ausgewählt und der App-Installer wird aufgerufen. Im Gegensatz zu den vorgenannten Optionen braucht hierbei das „Querladen“ von Apps oder der Entwicklermodus nicht aktiviert zu werden.
Package Support Framework
Nicht nur an den gerade vorgestellten Modifikationspaketen lässt sich feststellen, dass Enterprise-Funktionalitäten bei MSIX einen sehr hohen Stellenwert einnehmen. Mit MSIX wird zudem das Package Support Framework [11] bereitgestellt, durch das die Funktionsfähigkeit von Alt-Anwendungen sichergestellt werden kann.Bei vielen Alt-Anwendungen ist es noch so, dass Konfigurationsdateien im Anwendungsverzeichnis abgelegt werden und der Zugriff auf das Verzeichnis mit der .NET-Eigenschaft Environment.CurrentDirectory realisiert wurde. Eine solche Anwendung lässt sich völlig problemlos mit dem MSIX Packaging Tool in ein MSIX-Paket oder mit dem Desktop App Converter [12] in ein APPX-Paket umwandeln und bereitstellen. Beim Ausführen der App und dem Zugriff auf die Konfigurationsdatei kommt es aber zu einer FileNotFoundException. Das hat damit zu tun, dass bei einem APPX- oder MSIX-Paket der Verweis auf das Arbeitsverzeichnis nicht auf das naheliegende Verzeichnis gesetzt wird, sondern in Abhängigkeit zur Prozessorarchitektur auf C:\Windows\SysWOW64 oder C:\Windows\System32. Die benötigte Konfigurationsdatei kann nicht gefunden werden und eine Ausnahme wird ausgelöst.Eine Änderung des Algorithmus zum Zugriff auf die Datei führt hierbei auch nicht zum Erfolg, da der Ort, an dem die Store-Apps abgelegt werden, durch das System geschützt ist. Es ist somit erforderlich, die interne Implementierung in der Form zu verändern, dass die Anwendung einen geeigneten Speicherort für die Konfigurationsdateien nutzt. Dies setzt jedoch den Zugriff auf den Quellcode der Anwendung voraus.Mit MSIX und dem Package Support Framework ist es möglich, diese Problematik „von außen“, also ohne Programmierung der Anwendung, zu lösen. Hierzu stellt das Framework diverse Shims zur Verfügung.Die gerade skizzierte Problemstellung lässt sich mit dem FileRedirectionShim lösen. Hierdurch wird ein Runtime-Fix erstellt, der den Ordnerzugriff dynamisch umleitet.Fazit
MSIX nutzt das Beste aus allen Welten und soll alle bisherigen Installationstechnologien vereinen. Mit MSIX werden die Stabilität und die Enterprise-Funktionalität des Windows Installer, die Auto-Update-Funktionalität von ClickOnce und die Sicherheitsmerkmale von App-V mit dem Containerformat von APPX vereint.Die Definition des Formats ist Open Source und wird auf [13] veröffentlicht. Tools zum Erstellen und Entpacken der MSIX-Pakete stehen für die Plattformen Android, iOS und Linux bereit. Darüber hinaus wird die Verwendung von MSIX-Paketen auch unter Windows 7 möglich sein. Leidige Themen im Enterprise-Segment wie der Zugriff auf die Originalinstallationsquellen und massenhafte Computerneustarts werden reduziert oder gar beseitigt.Die neuen Enterprise-Funktionaltäten stellen wirkungsvolle Lösungen bereit, mit denen die Updatezyklen in modernen IT-Umgebungen effektiv umgesetzt werden können, wie das auch Bild 10 zeigt. Darüber hinaus hält die MSIX-Technologie eine Fülle von weiteren neuen Möglichkeiten bereit und wird sich mit den nächsten Windows-Versionen drastisch weiterentwickeln. So sind bereits jetzt neue Funktionalitäten und Tools angekündigt, die jede Menge Stoff für weitere Artikel zu MSIX liefern.Fussnoten
- DLL-Konflikt, http://www.dotnetpro.de/SL1902MSIX1
- Click-to-Run: Delivering Office in the 21st Century, http://www.dotnetpro.de/SL1902MSIX2
- Andreas Kerl, Eingedost, dotnetpro 1/2017, Seite 102 ff., http://www.dotnetpro.de/A1701Centennial
- Open Packaging Conventions, http://www.dotnetpro.de/SL1902MSIX3
- Behind the scenes of your packaged desktop application, http://www.dotnetpro.de/SL1902MSIX4
- Summary Information Stream Property Set, http://www.dotnetpro.de/SL1902MSIX5
- Resource Management System, http://www.dotnetpro.de/SL1902MSIX6
- Packaging API, http://www.dotnetpro.de/SL1902MSIX7
- Package manifest schema reference for Windows 10, http://www.dotnetpro.de/SL1902MSIX8
- MSIX Packaging Tool, http://www.dotnetpro.de/SL1902MSIX9
- MSIX Package Support Framework, http://www.dotnetpro.de/SL1902MSIX10
- Andreas Kerl, Vom Desktop in den Store, dotnetpro 2/2017, Seite 118 ff., http://www.dotnetpro.de/A1702Centennial
- MSIX SDK, http://www.dotnetpro.de/SL1902MSIX11