Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 14 Min.

Sauber getrennte Pakete

MSIX verringert die Fehleranfälligkeit und bietet zukunftsweisende Ansätze.
Es ist ein altes Problem, das wohl jeder Softwareentwickler kennt: Während auf dem Entwicklungsrechner alles problemlos funktionierte, kommt es auf dem Produktivsystem, auf dem die neue Anwendung installiert wird, zu massiven Problemen. Fehlende Ressourcen, Instabilitäten, Seiteneffekte mit anderen Anwendungen und komplexe Nutzereinstellungen torpedieren die Ausführung.Glücklicherweise gibt es heute Technologien, die diese Probleme in den Griff bekommen, sodass solche Erfahrungen der Vergangenheit angehören sollten. Dazu gehört Microsofts MSIX-Technologie, welche die dotnetpro in einem zweiteiligen Artikel genauer erläutert. Der erste Teil ist in der August-Ausgabe erschienen [1]. Was nun noch fehlt, klärt der vorliegende zweite Teil: das Zuweisen von Argumenten und das Verknüpfen von Anwendungspaketen.

Zuweisen von Argumenten

Bei der bereits im ersten Teil verwendeten Beispielanwendung MSIX Media Player handelt es sich um eine Windows-Forms-Anwendung, die über Aufrufparameter gesteuert werden kann. Listing 1 zeigt, wie beim Programmstart zunächst geprüft wird, ob es eine Konfigurationsdatei gibt. Falls nicht, erfolgt ein Upgrade und die Einstellungen der Vorversion werden übernommen. Die Variable FirstRun steuert dabei den automatisierten Aufruf des Konfigurationsdialogs, sodass er nur beim ersten Start erscheint. Hierzu wird die Variable nach der Konfiguration auf false gesetzt.
Listing 1: Steuerung der Anwendungskonfiguration
[STAThread] <br/>static void Main(<span class="hljs-built_in">string</span>[] <span class="hljs-built_in">args</span>) <br/>{ <br/>  // Prüfen auf erforderliches Upgrade der<br/>  // Konfigurationsdatei <br/>  <span class="hljs-keyword">if</span> (!ConfigurationManager.OpenExeConfiguration(<br/>      ConfigurationUserLevel.PerUserRoamingAndLocal).<br/>      HasFile) <br/>    Properties.Settings.Default.Upgrade(); <br/><br/>  // Standard ist True: Sofern kein Upgrade stattfand,<br/>  // wird der Einstellungsdialog aufgerufen <br/>  bool showSettingsDialog =<br/>    Properties.Settings.Default.FirstRun; <br/>  bool resetSettings = <span class="hljs-literal">false</span>; <br/><br/>  // Argumente auswerten: Übergabe von -config ist<br/>  // höherwertig <span class="hljs-literal">und</span> zeigt den Konfiguraionsdialog <br/>  // unabhängig von den bisherigen Einstellungen an. <br/>  foreach (<span class="hljs-built_in">string</span> arg <span class="hljs-keyword">in</span> <span class="hljs-built_in">args</span>) <br/>  { <br/>    <span class="hljs-keyword">if</span> (arg.Equals(<span class="hljs-string">"-config"</span>)) <br/>      showSettingsDialog = <span class="hljs-literal">true</span>; <br/>    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (arg.Equals(<span class="hljs-string">"-safe"</span>)) <br/>      Program.IsSafeMode = <span class="hljs-literal">true</span>; <br/>    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (arg.Equals(<span class="hljs-string">"-reset"</span>)) <br/>      resetSettings = <span class="hljs-literal">true</span>; <br/>  } <br/><br/>  <span class="hljs-keyword">if</span> (resetSettings) <br/>    Program.ResetSettings(); <br/><br/>  <span class="hljs-keyword">if</span> (showSettingsDialog) <br/>    Program.ShowConfigForm(<span class="hljs-literal">true</span>); <br/>  <span class="hljs-keyword">else</span> <br/>    Application.Run(<span class="hljs-built_in">new</span> MainForm()); <br/><br/>} 
Zur unabhängigen Steuerung kann zudem das Argument -config übergeben werden, sodass der Konfigurationsdialog auch ohne Abhängigkeit von der Variablen FirstRun aufgerufen wird. Die zusätzlichen Argumente -safe und -reset ermöglichen weitere Anwendungssteuerungen.Die Anwendung selbst ist in einer MSIX-Datei verpackt, sodass sie über die Kachel gestartet werden kann. Hierbei kommt zunächst nur der Konfigurationsautomatismus zum Tragen, da die Verwendung von Argumenten bei MSIX ein Umdenkens erfordert.MSIX-Pakete werden unterhalb des geschützten Verzeichnisses %ProgramFiles%\WindowsApps installiert. Somit finden sich in %ProgramFiles%\WindowsApps\MSIXMediaPlayerApp_1.0.55.0_x64__p1z 46hfsarpje\MSIXMedia die Binärdateien der Anwendung. Sofern der Nutzer Zugriff auf den Ordner hat, kann sie als Win32-Anwendung gestartet werden:
Process.Start(
  @"C:<span class="hljs-symbol">\P</span>rogram Files<span class="hljs-symbol">\W</span>indowsApps<span class="hljs-symbol">\</span>
<span class="hljs-symbol"> </span>   MSIXMediaPlayerApp_1.0.55.0_
    x64__p1z46hfsarpje<span class="hljs-symbol">\M</span>SIXMedia<span class="hljs-symbol">\</span>
<span class="hljs-symbol"> </span>   MSIXMedia.exe"); 
Falls die Anwendung keine Funktionalitäten der Windows-Runtime nutzt oder diese bei nativer Ausführung ignoriert, sollte sie wie erwartet funktionieren. Da sie im Win32-Modus ausgeführt wird, lassen sich wie gewohnt Befehlszeilenargumente übergeben. Allerdings ist das nicht zielführend und hat mit der MSIX-Technologie nichts zu tun. Die Nutzung des Anwendungscontainers steht hierbei im Fokus, wofür ein Aufruf von CreateProcess() mit Angabe der EXE-Datei nicht ausreicht. Hierfür müssen die Kernkomponenten verwendet werden, die auch in der Manifestdatei zu finden sind, siehe Listing 2:
Listing 2: Paket und Anwendungsidentität
&lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;Package&lt;/span&gt; &lt;span class="hljs-attr"&gt;...&lt;/span&gt; &amp;gt;&lt;/span&gt; &lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;Identity&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;    &lt;span class="hljs-attr"&gt;Name&lt;/span&gt;=&lt;span class="hljs-string"&gt;"MSIXMediaPlayerApp"&lt;/span&gt; &lt;span class="hljs-attr"&gt;Publisher&lt;/span&gt;=&lt;span class="hljs-string"&gt;"CN=MSIX"&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;    &lt;span class="hljs-attr"&gt;Version&lt;/span&gt;=&lt;span class="hljs-string"&gt;"1.0.55.0"&lt;/span&gt; &lt;span class="hljs-attr"&gt;ProcessorArchitecture&lt;/span&gt;=&lt;span class="hljs-string"&gt;"x64"&lt;/span&gt;/&amp;gt;&lt;/span&gt; &lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;Applications&lt;/span&gt;&amp;gt;&lt;/span&gt; &lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;Application&lt;/span&gt; &lt;span class="hljs-attr"&gt;Id&lt;/span&gt;=&lt;span class="hljs-string"&gt;"App1"&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;      &lt;span class="hljs-attr"&gt;Executable&lt;/span&gt;=&lt;span class="hljs-string"&gt;"MSIXMedia.exe"&lt;/span&gt; &lt;span class="hljs-attr"&gt;...&lt;/span&gt; /&amp;gt;&lt;/span&gt; &lt;br/&gt;    &lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;Application&lt;/span&gt; &lt;span class="hljs-attr"&gt;Id&lt;/span&gt;=&lt;span class="hljs-string"&gt;"App2"&lt;/span&gt; &lt;span class="hljs-attr"&gt;Executable&lt;/span&gt;=&lt;span class="hljs-string"&gt;"Helper.exe"&lt;/span&gt; &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-tag"&gt;      &lt;span class="hljs-attr"&gt;...&lt;/span&gt; /&amp;gt;&lt;/span&gt; &lt;br/&gt;  &lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;Applications&lt;/span&gt;&amp;gt;&lt;/span&gt; &lt;br/&gt;&lt;span class="hljs-tag"&gt;&amp;lt;/&lt;span class="hljs-name"&gt;Package&lt;/span&gt;&amp;gt;&lt;/span&gt; 
  • <Package>: Definiert die Umgebung, in welcher der gesamte Code ausgeführt wird, und beschreibt somit die Struktur und die Funktionen der Software auf dem System. Entscheidend für die Paketausführung ist die Angabe von PackageFamilyName, der sich wie in Bild 1 gezeigt aus dem Paketnamen und einem Hashwert des Publishers zusammensetzt, wobei die Werte durch einen Unterstrich voneinander getrennt sind; siehe hierzu auch den ersten Teil dieser Serie [1].
Die Bestandteileeiner MSIX-Paketidentität(Bild 1) © Autor
  • <Application>: Eine oder mehrere Anwendungen, die über eine Kachel gestartet werden. Erforderlich ist hierzu die Definition der Anwendungs-ID (Id). Dies ist ein ASCII-String mit einer Länge zwischen 1 und 64 Zeichen. Diese ID fungiert als eindeutiges Identifizierungsmerkmal der Anwendung innerhalb des Pakets. Die Identifizierung ist nötig, da es in einem Paket mehrere Anwendungen geben kann.
Um eine App im Anwendungscontainer auszuführen, gilt es zunächst, die beiden Identifizierungsmerkmale zu bestimmen. Hierzu eignet sich die Windows PowerShell:
PS C:\&gt; (Get-AppxPackage -Name
  "msixmediaplayerapp").
  PackageFamilyName 
PS C:\&gt; (Get-AppxPackage -Name
  "msixmediaplayerapp" | 
  Get-AppxPackageManifest).
  package.applications.
  application.id 
Es geht aber auch über die Windows-Nutzeroberfläche. Im Dialog Ausführen oder in der A­dresszeile des Windows-Explorers ist hierzu der Befehl shell:appsFolder einzugeben. Daraufhin öffnet sich ein Explorer-Fenster, das alle installierten Anwendungen auflistet. Nun ist lediglich eine Verknüpfung zu der benötigten Anwendung auf dem Desktop zu erstellen. Obwohl hiermit ein Anwendungspaket referenziert wurde, verfügt die Verknüpfung über das Standardkontextmenü, in dem die in Bild 2 dargestellten Paketeigenschaften angezeigt werden.
Der Eigenschaftendialogeiner Verknüpfung zu einem Anwendungspaket(Bild 2) © Autor
Entscheidend ist hier das Ziel der Verknüpfung. Hier finden sich die Bezeichnung PackageFamiliyName und die Anwendungs-ID, die durch ein Ausrufzeichen voneinander getrennt sind. Leider können die Werte nicht editiert werden, sodass sich der Verknüpfung keine Argumente anfügen lassen.Da nun die Identifizierungsmerkmale und somit die Aufrufsyntax bekannt sind, ist der parametrisierte Anwendungsaufruf über Konsole oder PowerShell möglich:
PS C:\&gt; start-process shell:appsfolder\MSIXMediaPlayerApp
  _p1z46hfsarpje!App -ArgumentList -config 

C:\&gt; start shell:appsfolder\MSIXMediaPlayerApp_
  p1z46hfsarpje!App -config 
Der Aufruf ist durch die kryptische Zielangabe nicht gerade intuitiv zu verwenden. Effektiver und einfacher wäre es, einen Alias zu nutzen. In den Windows-Einstellungen sind unter Apps | Apps und Features | Aliase für die App-Ausführung alle konfigurierten Aliase aufgeführt. Sofern es bereits einen Alias für die benötigte Anwendung gibt, umso besser. Falls nicht, muss das Anwendungspaket durch Modifikation der Datei AppxManifest.xml erweitert werden, wie es in Listing 3 geschieht. Erkennbar ist zunächst die Anwendung, die durch die Zeichenfolge App identifiziert wird und auf die Datei MSIXMedia
.exe
verweist. Darunter finden sich die Erweiterungen. Zur Nutzung ­eines Alias wurde die Extension <uap3:AppExecutionAlias /> hinzugefügt und der Alias msix-media.exe zugeordnet.
Listing 3: Definition von Alias und Parameter
&amp;lt;Application Id="App"&lt;br/&gt;    Executable="MSIXMedia\MSIXMedia.exe"&lt;br/&gt;    EntryPoint="Windows.FullTrustApplication"&lt;br/&gt;    uap10:Parameters="-safe"&amp;gt; &lt;br/&gt;  &amp;lt;Extensions&amp;gt; &lt;br/&gt;    &amp;lt;uap3:Extension&lt;br/&gt;        Category="windows.appExecutionAlias"&lt;br/&gt;        EntryPoint="Windows.FullTrustApplication"&lt;br/&gt;        Executable="MSIXMedia\MSIXMedia.exe"&amp;gt; &lt;br/&gt;      &amp;lt;uap3:AppExecutionAlias&amp;gt; &lt;br/&gt;        &amp;lt;desktop:ExecutionAlias&lt;br/&gt;          Alias="msix-media.exe"/&amp;gt; &lt;br/&gt;      &amp;lt;/uap3:AppExecutionAlias&amp;gt; &lt;br/&gt;    &amp;lt;/uap3:Extension&amp;gt; &lt;br/&gt;  &amp;lt;/Extensions&amp;gt; &lt;br/&gt;&amp;lt;/Application&amp;gt; 
Fortan lässt sich das Anwendungspaket über den Alias starten, wobei Argumente verwendet werden können. Angaben zu dem Alias lassen sich über die Windows-Einstellungen, aber auch mit entsprechenden Tools wie MSIX Hero [2] herausfinden. Bild 3 zeigt, dass die Beispielanwendung sowohl über eine Startmenükachel als auch über den Alias aufgerufen werden kann. Der Aufruf über die Konsole oder die Windows PowerShell ist natürlich ebenfalls möglich:
Die AufrufoptionenderBeispielanwendung(Bild 3) © Autor
PS C:\&gt; Start-Process msix-media.exe -ArgumentList
  -config 

C:\&gt; msix-media.exe -config 
Einen Überblick über alle Aliase auf dem System kann man sich mit dem Windows-Explorer oder der Konsole auf Dateiebene verschaffen, da Windows alle Aliase unter %Local­AppData%\Microsoft\WindowsApps speichert. An diesem Ort wird für jede Anwendung, die über einen Alias verfügt, ein Unterordner angelegt. Als Ordnername wird der Wert von PackageFamilyName verwendet. In dem jeweiligen Ordner befindet sich für jede mit einem Alias versehene Anwendung des Pakets eine EXE-Datei, die eine spezielle Form von IO_REPARSE_TAG_APPEXECLINK [3] verwendet, um auf das eigentliche Anwendungspaket zu verweisen. Die EXE-Datei trägt den Namen des Alias.Sofern die Verwendung des Alias für die jeweilige Anwendung in den Windows-Einstellungen unter Apps | Apps und Features | Aliase für die App-Ausführung aktiviert wurde, wird die EXE-Datei zusätzlich in den Windows-Apps-Ordner kopiert und der Aufruf ist fortan über den Alias möglich. Falls der Aufruf fehlschlagen sollte, ist die Ursache häufig in den Umgebungsvariablen des Nutzers zu finden. Zur fehlerfreien Verwendung muss der Windows-Apps-Ordner in die PATH-Variable aufgenommen sein.Mit der PowerShell ist es ebenfalls möglich, die Aliase zu betrachten und zu verwalten. Hierzu muss jedoch das Power­Shell-Modul NtObjectManager [4] installiert werden. Danach stehen die Funktionen Get-ExecutionAlias und Set-ExecutionAlias für diese Zwecke zur Verfügung. Einen tieferen Einblick in die Alias-Nutzung sowie die Verwendung des Moduls gibt das Blog „Tyranid’s Lair“ [5].Der parametrisierte Aufruf des Anwendungspakets kann innerhalb der Datei AppxManifest.xml definiert werden. Hierzu sind dem Attribut uap10:Parameters die benötigten Argumente zuzuordnen, wie es Listing 3 zeigt. Die Umsetzung ist einfach, offenbart aber einige Probleme:
  • Die zugeordneten Argumente werden bei jedem Anwendungsstart über die Kachel verwendet.
  • Bei der Verwendung des Befehls shell:appsfolder\MSIXMediaPlayerApp_p1z46hfsarpje!App -config wird das Argument -config der Parameters-Auflistung des Manifests hinzugefügt. Das gilt auch bei Parametern mit Wertzuweisung. Wurde im Manifest Test=1 definiert und über die Konsole Test=2 zugewiesen, werden beide Wertepaare an die Anwendung übertragen.
  • Bei der Verwendung des Alias werden die im Manifest definierten Parameter nicht berücksichtigt.
Solange sich die Anwendung problemlos ausführen lässt, können die Einschränkungen oft vernachlässigt werden. Kommt es beim Anwendungsstart hingegen zu einem Fehler, wird die Ursachenforschung durch die abweichenden Ergebnisse und Algorithmen erschwert.Je nach Anforderungskatalog kann die Nutzung einer gleichbleibenden Parametrisierung eine zweckmäßige Vorgehensweise darstellen. Immerhin ist es möglich, mehrere Anwendungen in einem MSIX-Paket zu bündeln. Es ist daher auch möglich, eine Anwendung mit unterschiedlichen Aufrufparametern zu referenzieren, wie das in Listing 4 aufgezeigt wird.
Listing 4: App mit verschiedenen Parametern starten
&amp;lt;Package...&amp;gt; &lt;br/&gt;  &amp;lt;Applications&amp;gt; &lt;br/&gt;    &amp;lt;Application Id="App1"&lt;br/&gt;        Executable="MSIXMedia.exe"&lt;br/&gt;        uap10:Parameters="-config" ...&amp;gt; &lt;br/&gt;      &amp;lt;uap:VisualElements&lt;br/&gt;      DisplayName="MSIX Media Player Config" ... /&amp;gt; &lt;br/&gt;    &amp;lt;/Application&amp;gt; &lt;br/&gt;    &amp;lt;Application Id="App2"&lt;br/&gt;        Executable="MSIXMedia.exe" ...&amp;gt; &lt;br/&gt;      &amp;lt;uap:VisualElements&lt;br/&gt;        DisplayName="MSIX Media Player" /&amp;gt; &lt;br/&gt;    &amp;lt;/Application&amp;gt; &lt;br/&gt;  &amp;lt;/Applications&amp;gt; &lt;br/&gt;&amp;lt;/Package&amp;gt; 
Sofern die Anwendung mit dem Microsoft DesktopApp-Installer bereitgestellt wird, findet sich auf der Nutzeroberfläche eine Option zum automatischen Starten der Anwendung nach Fertigstellung der Installation, wie es in Bild 4 zu sehen ist. Sofern ein Paket mehrere Anwendungen enthält, wird immer die gestartet, die in der Applications-Auflistung an erster Stelle steht. Von daher scheint es ideal, die Anwendung mit dem Konfigurationsaufruf dort zu platzieren.
Die Nutzeroberflächeeiner MSIX-Installation(Bild 4) © Autor

Deaktivierung des ms-appinstaller-Protokolls

Grundsätzlich besteht auch die Möglichkeit, Installationsparameter über einen Download- oder Installations-URI zu übergeben [6]. Hierzu wird das Protokoll ms-appinstaller verwendet, das letztlich den Microsoft DesktopApp-Installer aufruft. Aus Sicherheitsgründen hat Microsoft die Nutzung dieses Protokolls deaktiviert. Zum Zeitpunkt, als dieser Artikels entstand, war nicht abzusehen, ob und wann die Nutzung wieder möglich ist.

Flexible Virtualisierung

Klassische Win32-Anwendungen können Ordner und Dateien an vielen Stellen des Dateisystem erstellen, ändern oder löschen, sofern die erforderlichen Berechtigungen vorliegen. Gleiches gilt für Eintragungen in der Systemregistrierung. Charakteristisch ist hierbei die identische Sicht aller Anwendungen auf die Ressourcen. Änderungen können von allen Anwendungen ausgeführt werden, sodass Inkonsistenzen und sich daraus ergebende Seiteneffekte zwischen den Anwendungen nahezu unvermeidbar scheinen. Bei der Deinstallation der Anwendung bleiben die Ressourcen auf dem System, obwohl sie oft nicht mehr benötigt werden.Wie bereits erläutert, hat Microsoft dieses Verhalten im MSIX-Umfeld gravierend gerändert. Dateien, Ordner und Registrierungseinträge werden in einem privaten Bereich virtualisiert, sodass sie sich nur von derjenigen Anwendung wahrnehmen und ändern lassen, die sie auch erstellt hat. Bei der Deinstallation werden auch diese Elemente entfernt, sodass keine unnötigen Ressourcen auf dem System verbleiben.Sofern ausschließlich paketierte Anwendungen betrachtet werden, ist diese Lösung ideal. Die Vorsteile sind:
  • rückstandsfreie Deinstallation,
  • keine Beeinträchtigung anderer Anwendungen.
Durch Modifikationspakete und den weiter unten erläuterten Shared Package Container ist zudem ein paketübergreifender Zugriff auf den privaten Speicherbereich möglich. Gerade bei der Migration von „alten“ Anwendungen in die neue MSIX-Welt ist es nicht immer möglich, machbar und sinnvoll, alle bestehenden Anwendungen gemeinsam zu migrieren. Oft ist es nötig, die alte und die neue Technologie gemeinsam zu nutzen. Problematisch ist hierbei hingegen, dass die ältere Anwendung nicht auf den virtualisierten Speicherbereich des MSIX-Pakets zugreifen kann, sodass Ressourcen nicht gemeinsam verwendet werden können.Zur Realisierung solcher Szenarien wurde die Virtualisierungsfunktionalität der MSIX-Technologie erweitert. In der Datei AppxManifest.xml lässt sich nun festlegen, ob alle oder nur bestimmte Dateien und Registrierungseinträge für andere Anwendungen verfügbar sein sollen, wodurch sie auch nach der Deinstallation des Pakets auf dem System bleiben. Der Umfang, der Detailgrad, die Einschränkungen und die Vorgehensweise sind von der verwendeten Version des Betriebssystems abhängig.Mit Windows-Version 1903 hat Microsoft für solche Szenarien die folgende Funktion bereitgestellt:
&lt;rescap:Capability Name="unvirtualizedResources"/&gt; 
Darüber hinaus kann der Schreibzugriff durch die Eigenschaften RegistryWriteVirtualization und FileSystemWriteVirtualization des Namensraums uap6 konfiguriert werden. Sofern die Eigenschaften auf Disabled gesetzt wurden, werden die Schreibzugriffe auf HKCU und/oder den AppData-Ordner nicht virtualisiert und erfolgen somit im nativen Speicherbereich. Hierdurch sind die Modifikationen auch für Prozesse außerhalb des Pakets sichtbar. Bei der Deinstalla­tion erfolgt keine Bereinigung des Speicherbereichs. Der Standardwert beider Eigenschaften ist Enabled.Was auf den ersten Blick spannend anmutet, offenbart bei genauerer Betrachtung zwei große Schwachpunkte:
  • Der Mechanismus schaltet die Dateisystem- und HKCU-Virtualisierung aus, was dem eigentlichen Grundgedanken der Paketisolierung widerspricht.
  • Die Installation per DesktopApp-Installer wird nicht unterstützt, da das Paket die eingeschränkte Funktion unvirtualizedResources verwendet; die Installation ist somit nur per PowerShell möglich.
Um den Schwachstellen der bisherigen Implementierung entgegenzuwirken, erweitert Windows Version 21H1 die Funktionen nochmals. Hierdurch lassen sich die Umfänge exakter definieren, indem Ordner und Registrierungsschlüssel deklariert werden, die von der Virtualisierung ausgeschlossen werden. Allerdings gibt es auch hier Voraussetzungen:
  • Es können nur Orte im Dateisystem verwendet werden, die sich innerhalb von %USERPROFILE%\AppData befinden.
  • Es können nur Speicherorte der Systemregistrierung deklariert werden, die in HKCU enthalten sind.
Die Realisierung erfolgt über die hier identisch bezeichneten Eigenschaften RegistryWriteVirtualization und FilesystemWriteVirtualization, die sich aber im Gegensatz zu der bisherigen Implementierung in einem anderen Namensraum befinden. Vorteilhaft ist hingegen, dass hier die eingeschränkte Funktion unvirtualizedResources nicht verwendet werden muss, sodass der Installation per DesktopApp-Installer nichts im Wege steht.Listing 5 stellt beide Implementierungen dar. Während bei der alten Implementierung die komplette Dateisystem-Virtualisierung ausgeschaltet wird, erfolgt dies bei der neuen Implementierung nur für den Ordner %LocalAppData%\MSIXMedia.
Listing 5: Flexible Virtualisierung bei MSIX-Paketen
&amp;lt;Package ...&amp;gt; &lt;br/&gt;  &amp;lt;Properties&amp;gt; &lt;br/&gt;    &amp;lt;uap6:FileSystemWriteVirtualization&amp;gt;disabled&lt;br/&gt;    &amp;lt;/uap6:FileSystemWriteVirtualization&amp;gt; &lt;br/&gt;    &amp;lt;uap6:RegistryWriteVirtualization&amp;gt;enabled&lt;br/&gt;    &amp;lt;/uap6:RegistryWriteVirtualization&amp;gt; &lt;br/&gt;    &amp;lt;!--Neu seit Windows Version 21H1--&amp;gt; &lt;br/&gt;    &amp;lt;virtualization:FileSystemWriteVirtualization&amp;gt; &lt;br/&gt;      &amp;lt;virtualization:ExcludedDirectories&amp;gt; &lt;br/&gt;        &amp;lt;virtualization:ExcludedDirectory&amp;gt;&lt;br/&gt;          $(KnownFolder:LocalAppData)\MSIXMedia&lt;br/&gt;        &amp;lt;/virtualization:ExcludedDirectory&amp;gt; &lt;br/&gt;      &amp;lt;/virtualization:ExcludedDirectories&amp;gt; &lt;br/&gt;    &amp;lt;/virtualization:FileSystemWriteVirtualization&amp;gt; &lt;br/&gt;  &amp;lt;/Properties&amp;gt; &lt;br/&gt;  &amp;lt;Capabilities&amp;gt; &lt;br/&gt;    &amp;lt;rescap:Capability Name="runFullTrust" /&amp;gt; &lt;br/&gt;    &amp;lt;!--Seit Windows Version 1903--&amp;gt; &lt;br/&gt;    &amp;lt;rescap:Capability&lt;br/&gt;      Name="unvirtualizedResources" /&amp;gt; &lt;br/&gt;  &amp;lt;/Capabilities&amp;gt;&lt;br/&gt;&amp;lt;/Package&amp;gt; 
Es ist möglich, in einem Paket beide Deklarationsvarianten zu verwenden. In einem solchen Fall wird die alte Funktionalität für Versionen vor Windows 10 21H1 genutzt, während die neue Option bei Windows 10 21H1 und später zum Einsatz kommt.

Ressourcen außerhalb des App-Verzeichnisses

Im MSIX-Universum werden üblicherweise alle Ressourcen in einem isolierten Bereich abgelegt, sodass nur die jeweilige Anwendung darauf zugreifen kann. Ausnahmen davon sind durch die Deaktivierung der Virtualisierung für die Nutzerbereiche möglich. Seit Windows 11 besteht zudem die Möglichkeit, das Anwendungsverzeichnis an einem beliebigen Speicherort zu platzieren, sodass der Zugriff auch von anderen Anwendungen möglich ist.Beide Verfahren haben gewisse Unwägbarkeiten. So bleiben bei der ersten Option nach der Deinstallation die nicht virtualisierten Ressourcen auf dem System, während bei der zweiten Variante eine Provisionierung [7] zur systemweiten Bereitstellung des Pakets erforderlich ist. Die Notwendigkeit der zweiten Option ergibt sich daraus, dass der Paketordner %ProgramFiles%\WindowsApps geschützt ist und nur bestimmte Windows-Dienste darauf zugreifen können. Durch die Wahl eines alternativen Speicherorts wird hingegen eine Ordnerstruktur geschaffen, auf die jeder Administrator schreibend zugreifen kann. Da dieser Speicherort logisch mit dem Paket verbunden ist, kann die jeweilige Anwendung diesen wie gewohnt nutzen.Die Deklaration eines solchen alternativen Speicherorts erfolgt über das Element <MutablePackageDirectory/>, das in zwei Namensräumen zu finden ist:
  • <Desktop6:MutablePackageDirectory>: Das Verzeichnis wird unterhalb von %ProgramFiles%\ModifiableWindowsApps angelegt.
  • <Desktop8:MutablePackageDirectory>: Ein beliebiges Verzeichnis außerhalb des WindowsApps-Ordners kann als Ziel bestimmt werden, sofern Windows 11 verwendet wird.
Beide Varianten bieten den Zugriff auf die virtuelle Ordnerstruktur des Anwendungspakets mit jeder beliebigen Technologie. So können Ressourcen auf jede Weise kopiert oder entfernt werden, sofern die erforderlichen Berechtigungen vorliegen. Die Anwendung selbst wird nach wie vor unter %ProgramFiles%\WindowsApps gespeichert, sieht aber nur die Ressourcen in dem alternativen Verzeichnis, das bei der Deinstallation des provisionierten Pakets ebenfalls entfernt wird.Modifikationspakete bieten ähnliche Möglichkeiten. Ressourcen werden im isolierten Bereich des Modifikationspakets abgelegt, aber mit der Struktur des Hauptpakets zusammengeführt, sodass sie aus Sicht der Anwendung physisch an einem Ort erscheinen. Die Modifikationspakete lassen sich zudem unabhängig vom Hauptpaket weiterentwickeln und aktualisieren. Sie bleiben aber mit dem Hauptpaket verbunden, sodass sie bei seiner Deinstallation ebenfalls entfernt werden.Die vorgestellten Möglichkeiten decken ein großes Spek­trum der Ressourcenverwaltung ab, sodass anscheinend keine Wünsche offen bleiben. Aber der Schein trügt. Gerade bei komplexen Anwendungen zeigt sich ein weiterer Schwachpunkt: Es ist alles nur auf ein einzelnes Anwendungspaket ausgelegt.

Mehrere Anwendungspakete verknüpfen

Der Shared Package Container erweitert die vorgestellten Möglichkeiten zur gemeinsamen Ressourcennutzung erheblich. Hierbei handelt es sich um einen Laufzeitcontainer, der voneinander unabhängigen MSIX-Anwendungen eine gemeinsame Sicht auf das virtuelle Dateisystem und die virtuelle Systemregistrierung ermöglicht.Beim Beispiel des Media Players sind es die Anwendungspakete MSIXMedia, MSIXCalc und MSIXPackager. Jedes dieser Pakete verfügt über ein virtuelles Dateisystem mit zwei relevanten Ordnern. Ein Ordner ist mit dem Anwendungsnamen bezeichnet und enthält die Datei help.txt. Der andere Ordner ist mit MSIXOffice bezeichnet und enthält zwei Bilddateien mit dem jeweiligen Anwendungssymbol. Eine Bilddatei trägt den Anwendungsnamen, die andere ist mit ­logo.png bezeichnet.Nach der Installation agiert jedes Anwendungspaket zunächst autark. Das bedeutet, dass jede Anwendung nur den eigenen virtuellen Speicherbereich sehen und auf ihn zugreifen kann. Der Shared Package Container ändert das, wie auch Bild 5 zeigt. Jede Anwendung kann die Inhalte der individuell benannten und somit isolierten Ordner sehen und die help.txt-Dateien aller Anwendungspakete nutzen. Darüber ist der Zugriff auf den Ordner MSIXOffice möglich, der eine verbundene Sicht auf die gemeinsamen Ressourcen bietet.
Gemeinsame Sichtunabhängiger Anwendungen(Bild 5) © Autor
Die Bereitstellung eines Shared Package Containers kann unabhängig vom Softwarebereitstellungsprozess der Anwendung erfolgen. So kann der Container auf dem System bereits vor der Installation der Anwendungen registriert werden. Bei der Anwendungsinstallation erkennt das System den registrierten Container und fügt die Anwendungen hinzu. Der umgekehrte Weg ist ebenfalls möglich: Wird der Container nach den Anwendungen registriert, werden sie diesem automatisch zugewiesen.Die Aktualisierung der Anwendungen kann wie bisher erfolgen und obliegt keinerlei Einschränkungen durch die Containernutzung. Interessant ist auch das Verhalten bei Modifikationspaketen. Hierbei handelt es sich um Ergänzungen, die sich in den Anwendungscontainer des Hauptpakets virtuell einklinken. Für den Einsatz in einem Shared Package Container sind daher keine weiteren Vorkehrungen zu treffen.Sofern das Hauptpaket in den Container aufgenommen wurde, werden die Inhalte der Modifikationspakete ebenfalls zu der verbundenen Sicht hinzugefügt.Die gesamte Nutzung der Container ist sehr einfach gehalten. Dennoch gilt es einige Faktoren zu berücksichtigen:
  • Ein Shared Package Container wird in der Regel von IT-Professionals verwendet, da für die Verwaltung administrative Rechte erforderlich sind.
  • Die Registrierung erfolgt ausschließlich per PowerShell und setzt mindestens Windows 10 Insider Preview Build 21354 voraus.
  • Jedes Anwendungspaket kann nur in einen Shared Package Container aufgenommen werden. Der Versuch, ein bereits registriertes Paket auch in einen anderen Container aufzunehmen, führt zu einem Fehler.
Sofern diese Voraussetzungen zutreffen, kann ein Shared Package Container bereitgestellt werden. Hierzu wird lediglich eine XML-Datei benötigt. Im Element <AppSharedPackageContainer/> ist mit dem Name-Attribut zunächst der Container zu bezeichnen. Die einzubindenden Pakete werden mithilfe der Elemente <PackageFamily/> angefügt, wie es für die Beispielanwendungen erfolgt:
&lt;?xml version="1.0" encoding="utf-8"?&gt; 
  &lt;AppSharedPackageContainer Name="MSIXOfficeContainer"&gt; 
    &lt;PackageFamily
      Name="MSIXMediaPlayerApp_p1z46hfsarpje"/&gt; 
    &lt;PackageFamily Name="MSIXPackagerApp_p1z46hfsarpje"/&gt;
    &lt;PackageFamily Name="MSIXCalulatorApp_p1z46hfsarpje"/&gt; 
  &lt;/AppSharedPackageContainer&gt; 
Die eigentliche Bereitstellung des Shared Package Containers erfolgt mit dem Befehl Add-AppSharedPackageContainer in einer administrativen PowerShell-Konsole; ihm ist der Pfad zur XML-Datei anzufügen. Falls bereits ein Container mit identischem Namen auf dem System existiert, wird dieser überschrieben.Darüber hinaus empfiehlt es sich, das Argument -Force­ApplicationShutDown zu verwenden. Ohne dieses Argument würde der Befehl zu einem Fehler führen, sofern derzeit eine referenzierte Anwendung verwendet wird.
PS C:\&gt; Add-AppSharedPackageContainer
  "C:\MSIXOfficeContainer.xml" -ForceApplicationShutdown 
Bei erfolgreicher Ausführung werden die eindeutige ID und der Name des Containers ausgegeben. Der Befehl Get-AppSharedPackageContainer stellt diese Informationen ebenfalls bereit, fügt aber auch die involvierten Pakete der Ausgabe mit an:
PS C:\&gt; Get-AppSharedPackageContainer 

Id                : 11446959-11db-4394-992b-
                      53b59039b2e0 
Name              : MSIXOfficeContainer 
PackageFamilyNames : MSIXCalulatorApp_p1z46hfsarpje 
                    MSIXMediaPlayerApp_p1z46hfsarpje 
                    MSIXPackagerApp_p1z46hfsarpje 

Id                : ad96a240-1251-4d16-b621-
                      4ca9d6f64802 
Name              : MSIXOfficeContainer5 
PackageFamilyNames : MSIXNotepadApp_p1z46hfsarpje 
Alle weiteren PowerShell-Befehle zur Verwaltung der Shared Package Container sind in Tabelle 1 zusammengefasst.

Tabelle 1: Verwaltung von Shared Package Containern

  Befehl Erläuterung
Add-AppSharedPackageContainer Stellt den Container für den jeweiligen Benutzer bereit.
Remove-AppSharedPackageContainer -Name   Hebt die Bereitstellung des Containers für den jeweiligen Nutzer auf.
Get-AppSharedPackageContainer -Name Ruft Informationen zu dem spezifizierten oder dem Filter entsprechenden Container ab.
Reset-AppSharedPackageContainer -Name   Setzt die Anwendungsdaten des Containers zurück, einschließlich der virtuellen Dateien und Registrierungsschlüssel.
Shared Package Container ermöglichen eine gemeinsame Sicht auf das virtuelle Dateisystem und die virtuelle Registrierung aller inkludierten Anwendungspakete. Obwohl die Vorgehensweisen und Darstellungen einleuchtend und intui­tiv erscheinen, gilt es noch die anfängliche Frage zu klären, welches Logo eigentlich gewinnt.Jedes der Beispielpakete enthält im virtuellen Dateisystem den Ordner MSIXOffice, in den jedes Paket seine eigene Logo­datei unter dem Namen logo.png ablegt. Durch die gemeinsame Sicht der verlinkten Pakete auf diesen Ordner kann aber nur eine Logodatei gewinnen. In diesem Beispiel ist es das Logo der MSIXMedia-App, wie Bild 6 zeigt, da sich die Paketverlinkung an oberster Stelle der Containerdefini­tion befindet.
Der Ordnerinhalteiner verbundenen Ansicht(Bild 6) © Autor

Fazit

Mit diesem zweiten Artikel zur MSIX-Technologie findet das umfangreiche Thema vorerst seinen Abschluss. Während im Windows-Installer-Umfeld nahezu alle Konfigurationen innerhalb der Installationsphase erfolgten, führen die neuen Richtlinien zur Anwendungskonfiguration zu einer sauberen Trennung zwischen Installation und Konfiguration. Die Nutzeroberfläche für die Installation von MSIX-Paketen wurde dadurch vereinfacht, ist übersichtlicher und auf das Wesentliche beschränkt.Die Konfiguration wird in der Anwendung vorgenommen, wodurch die Fehleranfälligkeit während der Installationsphase deutlich gesenkt wird. Zahlreiche Implementierungen und Möglichkeiten unterstützen bei der effektiven Umsetzung dieses Paradigmas und bieten neue, zukunftsweisende Lösungsansätze bei der Bereitstellung von Anwendungen nicht nur in Migrations- und Transitionsszenarien.
Projektdateien herunterladen

Fussnoten

  1. Andreas Kerl, Komplexe Setups fest im Griff, MSIX-Anwendungseinstellungen – Teil 1, dotnetpro 8/2022, Seite 62 ff., http://www.dotnetpro.de/A2208MSIX
  2. MSIX Hero, https://msixhero.net
  3. Reparse Tags, http://www.dotnetpro.de/SL2209MSIX1
  4. NtObjectManager, http://www.dotnetpro.de/SL2209MSIX2
  5. Overview of Windows Execution Aliases, http://www.dotnetpro.de/SL2209MSIX3
  6. Passing installation parameters to your app via App Installer, http://www.dotnetpro.de/SL2209MSIX4
  7. Andreas Kerl, Unter der Haube von MSIX, MSIX-Pakete verwalten, dotnetpro 7/2020, Seite 26 ff., http://www.dotnetpro.de/A2007MSIX

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Evolutionäres Prototyping von Business-Apps - Low Code/No Code und KI mit Power Apps
Microsoft baut Power Apps zunehmend mit Features aus, um die Low-Code-/No-Code-Welt mit der KI und der professionellen Programmierung zu verbinden.
19 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige