Open DrusTheAxe opened 2 years ago
See https://github.com/microsoft/WindowsAppSDK/issues/2621#issuecomment-1158341320 for the latest discussion that sparked the creation of this issue
Windows.Storage.ApplicationData.Current only works fir you have package identity AND running in AppContainer
Nit: I'd add the word reliably in there (e.g. only works reliably), just to bring attention to how evil this API truly is. Because the API does work most of the time, it misleads devs and puts them on a path to failure.
Otherwise thanks for writing this up and moving the needle. I've been talking about these tricky APIs/scenarios since around 2017!
Windows.Storage.ApplicationData.Current only works if you have package identity AND running in AppContainer
Nit: I'd add the word reliably in there (e.g. only works reliably), just to bring attention to how evil this API truly is. Because the API does work most of the time, it misleads devs and puts them on a path to failure.
Can you elaborate on what you find unreliable about ApplicationData.Current?
Is it really unreliable or rather the complexity of having to understand the right contexts it does/not support (i.e. the Rationale's first 3 bullets)?
Can you elaborate on what you find unreliable about ApplicationData.Current?
ApplicationData.Current.LocalSettings
usage outside of AppContainer is on a best effort basis I'm told. Was a top crasher for EarTrumpet (runFullTrust app) until I replaced it recently with ApplicationDataManager.CreateForPackageFamily(...).LocalSettings
. 😎
ApplicationData.*Folder
only provide access to the filesystem viaStorageFolder
. There's no way to get their.Path
without going thrug aStorageFolder
incurring significant performance overhead
Can definitely see the importance of getting a filesystem Path without StorageFolder
. However, it would be valuable to know whether Microsoft sees the performance overhead as inevitable with StorageFolder
/StorageFile
. #8 is obviously a separate issue to tackle, but should new APIs really be built around paths if an improved StorageFolder
(or something new) is on the backlog?
EDIT: IDL in spec shows that both a StorageFolder and Path will be available for the given locations, so this seems like less of a statement on the future of StorageFolder and more about facilitating interoperability from non Windows.Storage APIs which take a filesystem path.
Gets a 👍🏻 from me
EDIT: IDL in spec shows that both a StorageFolder and Path will be available for the given locations, so this seems like less of a statement on the future of StorageFolder and more about facilitating interoperability from non Windows.Storage APIs which take a filesystem path.
Bingo! :-)
Just to let you know what I did (a manual and not an elegant solution) to walkaround the Windows.Storage.ApplicationData for now:
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
to replace the (path to) local storage folder (Windows.Storage.ApplicationData.Current.LocalFolder).Use XML for local settings (Windows.Storage.ApplicationData.Current.LocalSettings).
Edited: for my situation only as in discussion #2618
Use System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) to replace the (path to) local storage folder (Windows.Storage.ApplicationData.Current.LocalFolder).
BTW that's not equivalent. ApplicationData.LocalFolder
is a per-user location in your user profile1,2 but GetExecutingAssembly() is wherever the assembly is located (i.e. where your .exe or .dll lives). That could be in your user profile but could be lots other places, and it's the same answer for the assembly regardless of the user.
Windows.Storage.AppDataPaths.GetDefault().LocalAppData + \publisher\product
is the unpackaged equivalent to ApplicationData.Current.LocalFolder
-- a per-user location for data for the product/package.
Windows.Storage.AppDataPaths.GetDefault().LocalAppData == SHGetKnownFolderPath(KnownFolderID_LocalAppData...) == %LOCALAPPDATA% == %USERPROFILE%\AppData\Local (but APIs are better than environment variables as the latter can be trivially altered/hacked; they're not reliable or definitive sources of the answer, those APIs are).
1 Maybe. ApplicationData for a package family exists under %USERPROFILE% if the package is installed on %SystemDrive% (i.e. C:) but if you install packages to other drives then their ApplicationData will be created on the same drive e.g. install a packaged app on Q: and ApplicationData.LocalFolder will likewise be located on Q:
2 But that's not absolute. If you then move the package to another drive the package moves but not the data e.g. pkgmgr.MovePackageAsync(foo,...) from Windows.ApplicationModel.Package.InstalledPath=Q:... to M:... but ApplicationData will still be on Q:
Proposal: Microsoft.Storage.ApplicationData
Summary
Provide a modern enhanced version of Windows.Storage.ApplicationData and Windows.Management.Core.ApplicationDataManager
Microsoft-internal task 40050113
Rationale
Windows.Storage.ApplicationData.Current
only works if you have package identity AND running in AppContainerWindows.Management.Core.ApplicationDataManager.CreateForPackageFamily
is equivalent but requires you have package identity AND running MediumIL or higher%LOCALAPPDATA%\publisher\product
,%LOCALAPPDATA%\Temp
andHKCU\SOFTWARE\publisher\product
but ApplicationData doesn't support thatWindows.Storage.ApplicationData
has several deprecated and obsolete features (e.g. .RoamingFolder)ApplicationData.*Folder
only provide access to the filesystem viaStorageFolder
. There's no way to get their.Path
without going thrug aStorageFolder
incurring significant performance overheadApplicationData
has async methods which should be available synchronously e.g.ClearAsync()
should offer `Clear() as a synchronous variant (or replacement?)Windows App SDK can and should provide a modern revision of the
ApplicationData
API, addressing the issues above (one API supporting both packaged and unpackaged apps).Scope
Important Notes
Microsoft.Storage.ApplicationData supports packaged and unpackaged apps. The underlying data stores are different but equivalent(ish):
ApplicationData.LocalCacheFolder
%LOCALAPPDATA%\<publisher>\<product>
ApplicationData.LocalFolder
%LOCALAPPDATA%\<publisher>\<product>
ApplicationData.MachineFolder
%ProgramData%\<publisher>\<product>
ApplicationData.RoamingFolder
%LOCALAPPDATA%\Roaming
ApplicationData.TemporaryFolder
%LOCALAPPDATA%\Temp
ApplicationData.LocalSettings
HKCU\SOFTWARE\<publisher>\<product>
WinRT API
Here's a sketch of the general shape of the API to express the intent of the ask. The actual API when designed/spec'd/reviewed/approved may differ.
Microsoft.Storage.ApplicationData.idl
Open Questions
Q: Is there an unpackaged equivalent to GetPublisherCacheFolder()?