UWP / StoreApp では、アプリが「直で」アクセスできるのはアプリそれぞれが持つフォルダのみである!という原理原則があります。
File access permissions
https://msdn.microsoft.com/en-us/windows/uwp/files/file-access-permissions
Open files and folders with a picker
https://msdn.microsoft.com/en-us/windows/uwp/files/quickstart-using-file-and-folder-pickers
File access permissions
https://msdn.microsoft.com/en-us/windows/uwp/files/file-access-permissions
Open files and folders with a picker
https://msdn.microsoft.com/en-us/windows/uwp/files/quickstart-using-file-and-folder-pickers
この縛りがあるために、UWP / Store Appは他のUWP / Store Appや、ユーザーのファイルを直接触る事が不可能であり、窮屈だけど安全な環境になっております、という事になっています。
…が、原理原則だけでは人は生きては行けないので…Win10 UWP では多少その辺り柔軟な対応になってきています。ここでは、フォルダを介したデータ共有として有名なものと、そうでもないものを紹介します。
GetPublisherCacheFolder
https://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.getpublishercachefolder.aspx有名なほう。
- 同じマシン
- 同じユーザー
- 同じアプリベンダー
このフォルダにアクセスしたいアプリは、各々のアプリのPackage.appxmanifest でアクセスするフォルダ名を<Extensions>内で宣言する必要があります。
Package.appxmanifest
デザイナでは変更できないので、右クリック→「コードの表示」で編集します。
|
上のように宣言したアプリは、コード中で以下のようにフォルダにアクセスできます。
ポイントとしては、このフォルダはアプリから直でアクセスが可能です。Windows.Storage ... OSのBroker Process を介さずに、.NETならば System.IOで直で触ることができます。
CacheFolderに触っている様子 直アクセスOK |
なお、このフォルダの物理パスは
C:\Users\<UserName>\AppData\Local\Publishers\<publisherId>\<CacheFolderName>
になります。<CacheFolderName> は、上のManifestで指定した名前です。
SharedLocalFolder
https://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.sharedlocalfolder.aspx無名なほう。
- 同じマシン
- 同じアプリ
の、複数のユーザー間で共通に使えるフォルダです。
このフォルダにアプリからアクセスしたい場合、まず管理者がHKLMのレジストリを変更する必要があります。以下のKeyを作成し、DWORD Value "AllowSharedLocalAppData" を 1 にセットします。
上のRegistry Flagがセットされている場合、UWP Appから「SharedLocalFolder」にアクセスできます。ちなみに、Flagが0又は存在しない場合はfolderにnullが返ります(システムの既定ではKey "AppModel" 自体が無い)。また、このフォルダもアプリから直でアクセスが可能です。
なお、このフォルダの物理パスは
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager |
上のRegistry Flagがセットされている場合、UWP Appから「SharedLocalFolder」にアクセスできます。ちなみに、Flagが0又は存在しない場合はfolderにnullが返ります(システムの既定ではKey "AppModel" 自体が無い)。また、このフォルダもアプリから直でアクセスが可能です。
SharedLocalFolder に触っている様子 こちらも直アクセスOK |
なお、このフォルダの物理パスは
C:\ProgramData\Microsoft\Windows\AppRepository\Families\<PackageFamilyName>\SharedLocal
になります。フォルダ内で作成されたファイルはアクセス権が「Everyone-FullControl」になります。
また、このフォルダは上記Registry Value が設定されている場合、アプリ側で当該フォルダを使用しなくても勝手に作成されるようです。アプリ起動時のタイミングで作成されているように見えます(つまり、フラグをセットすると全UWP アプリでこのフォルダアクセスが有効になります。要注意)。
背景
UWP がお披露目となったBuild 2015では、UWP App 間でデータ共有を行う手段が幾つか追加されました、という文脈の中で前者 PublisherCacheFolder が紹介されていました。以降のWindows Blog等でも紹介されていたように記憶しています。
一方、後者のSharedLocalFolder はBuildでは完全にスルーでした(そのはず)。 VisualStudioでいそいそとコードを書いていると、ApplicationData.Current のIntelliSenseでチラチラ表示はされるので存在は知っていたのですが…いざMSDN Docを見ると木で鼻を括ったような全くなにも説明していない表記で、何ぞこれ???という。
状況が変わったのは以下のBlogで…MSのフィールドエンジニア氏がこんなんだよーと説明していました。まじか。
https://blogs.msdn.microsoft.com/notime/2016/03/04/sharing-data-between-users-of-a-universal-app/
ただ、実際こう見てみると…半ば隠しAPI扱いなのもやむを得ない感じですね。
HKLMの変更が必要であるため、UWPだけで使用可能になる類の物ではありません。管理者権限が必要です。
(Registry Editorの無いMobileや他のDeviceFamilyではどうすんだろう?という疑問もあります)
実際に使用されるケースは…LOB Appでの使用、All UserなWin32 Appとの協調動作を企図した使用等、かなり限定的なのではと思われます。