en
de

Zugriff auf das Filesystem aus der Windows 8 Sandbox

15 April 2013
| |
Lesezeit: 3 Minutes

Schon mal versucht von einer Desktop-Anwendung aus mit einer Windows 8 App zu kommunizieren? Dieser Datenaustausch steht dem Sandbox-Prinzip von Windows 8 ziemlich entgegen, ist aber trotzdem möglich.

Mit Windows Vista wurde die Trennung von Anwendungsdaten und Installationsdaten zur Pflicht. Programme dürfen seitdem nicht mehr auf das Installationsverzeichnis schreibend zugreifen, stattdessen sollen sie das Anwendungsverzeichnis unter AppData verwenden.

Apps können auf Filesystem-Ebene ohne weiteres nur auf eigene, für sie fest vorgegebene Verzeichnisse zugreifen. Die AppContainer-Integritätsstufe blockiert jede weitere Kommunikation zwischen den Apps.

Um den Apps die Modifikation eigener Daten zu ermöglichen, werden alle Dateien, die in das AppData-Verzeichnis einer App kopiert werden, von Windows 8 automatisch mit der Integritätsstufe Low versehen. Die Zugehörigkeit einer Datei oder eines Verzeichnisses zu einer Integritätsstufe kann über das Kommandozeilentool icacls gelesen und gesetzt werden. Die Information kann dabei dem Eintrag Mandatory Label\[x] Mandatory Level entnommen werden, wobei [x] die eingestellte Integritätsstufe anzeigt. Fehlt der Eintrag, gilt die Integritätsstufe Medium. Das Kommandozeilentool icacls zeigt dementsprechend für alle Dateien im AppData Verzeichnis den ACL Eintrag:

Mandatory Label\Low Mandatory Level

Zu jeder installierten App in WinRT existiert ein zugehöriger AppData Ordner im Verzeichnis des Benutzers, der diese App installiert hat. Je nach Einsatzzweck sind die folgenden Ordner für Apps nutzbar:

  • Zum Ablegen kurzfristiger Daten sieht Microsoft den Ordner Temporary vor. Die dort abgelegten Dateien werden durch die Laufzeitumgebung nach Beendigung der App zu einem beliebigen Zeitpunkt entfernt. Im Dateisystem ist dieser Ordner an diesem Ort zu finden:
    C:\Users\[Username]\AppData\Local\Packages\[Package Name]\TempState
  • Für Daten, die über die Laufzeit der App hinweg, aber nur auf dem aktuellen Gerät benötigt werden, ist der Ordner Local vorgesehen. Abgelegte Dateien werden erst nach dem Deinstallieren der App durch die Laufzeitumgebung entfernt. Dieser Ordner ist im Dateisystem an folgendem Ort zu finden:
    C:\Users\[Username]\AppData\Local\Packages\[Package Name]\LocalState
  • Der Ordner Roaming stellt Daten über Gerätegrenzen hinweg zur Verfügung. Dieser Speicher wird in die Microsoft Cloud synchronisiert und ist auf eine fixe Größe beschränkt. Die Größe kann aus der Property ApplicationData.Current.RoamingStorageQuota ausgelesen werden. Zurzeit sind lediglich 100 KB vorgesehen. Microsoft empfiehlt deshalb, den Einsatz von Roaming auf wenige Anwendungsfälle zu beschränken. Der Roaming Ordner ist im Dateisystem an folgendem Ort zu finden:
    C:\Users\[Username]\AppData\Local\Packages\[Package Name]\RoamingState

[Package Name] ist dabei der Name, der im App Manifest im Abschnitt Packaging angegeben wurde. Unter anderem sind in diesem Verzeichnis auch die Daten der vorinstallierten Microsoft Apps wie Bing News oder Zune Music zu finden.

Datenaustausch

Über das App-Datenverzeichnis ist es möglich, einen einfachen Nachrichtenaustausch zwischen einer Desktop-Anwendung und einer Windows Store App auf Dateisystemebene  einzurichten. Zunächst wird eine Datei im Local Ordner benötigt. Im Beispiel wird hier eine Textdatei verwendet. Es könnte sich dabei aber auch um eine dateibasierte Datenbank wie SQLite handeln.

Die auszutauschenden Daten werden sowohl von der App als auch von der Desktop-Anwendung in diese Datei geschrieben. Doch wie können die beiden Welten benachrichtigt werden, wenn neue Informationen in der Datei vorliegen?

In einer Desktop-Anwendung ist dies beispielsweise durch Verwendung der Klasse FileSystemWatcher möglich, die Dateiänderungen durch ein Event signalisiert.

FileSystemWatcher watcher = new FileSystemWatcher();

watcher.Path = "C:\Users\[Username]\AppData\Local\Packages\[Package Name]\LocalState\testfile.txt";
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite;
watcher.Filter = "testfile.txt";
watcher.Changed += OnChanged;
watcher.EnableRaisingEvents = true;

WinRT stellt die Klasse FileSystemWatcher nicht zur Verfügung. Zur Änderungsbenachrichtigung kann stattdessen auf das Event ContentsChanged einer Dateisuche (StorageFileQuery) zurückgegriffen werden. Dabei ist zu beachten, dass das Event erst nach dem einmaligen Ausführen der Dateisuche aktiv wird, d.h. es muss mindestens ein Aufruf von GetFilesAsync erfolgen.

Ein typischer Fehlerpunkt ist das zu frühe Löschen des Suchergebnisses. Wird das Ergebnisobjekt zerstört, erzeugt die Laufzeitumgebung keine Änderungsbenachrichtigungen für diese Suche mehr und das Abonnement des ContentsChanged Events ist nicht mehr vorhanden [18][19]. Dies kann beispielsweise durch das Rerenzieren des Ergebnisobjekts in einer ViewModel Instanz erfolgen.

var localFolder = ApplicationData.Current.LocalFolder;

if (this.storageFileQueryResult == null)
{
      this.storageFileQueryResult = localFolder.CreateFileQuery();
      this.storageFileQueryResult.ContentsChanged += ContentsChanged;
}

var fileList = await this.storageFileQueryResult.GetFilesAsync();

Die Methode ContentsChanged wird immer dann aufgerufen, wenn dem System Änderungen an Dateien gemeldet werden. Windows 8 sammelt dabei Änderungsbenachrichtigungen auch für Apps, die sich im Suspended Modus befinden. Die Events werden nachgeliefert, sobald die App wieder aktiv wird. Welche Datei sich wie geändert hat, ist allerdings nicht festzustellen, da diese Information durch die Laufzeitumgebung nicht mitgeliefert wird.

Ich bin gespannt, ob diese Methode für jemanden hilfreich ist. Aber auch wenn es nicht klappt, würde mich freuen davon zu hören.

Kommentare (0)

×

Updates

Schreiben Sie sich jetzt ein für unsere zwei-wöchentlichen Updates per E-Mail.

This field is required
This field is required
This field is required

Mich interessiert

Select at least one category
You were signed up successfully.