WindowsAppSDK
WindowsAppSDK copied to clipboard
Cannot create a folder or a file in any of KnownFolders' locations.
Describe the bug
Trying to create a file or folder in any location accessible via KnownFolders throws exceptions like, "could not be found. (0x80030002 (STG_E_FILENOTFOUND))" and "The system cannot find the file specified. (0x80070002)".
This can be easily reproduced by creating a simple new blank WinUI3 project and adding the following line of code.
await KnownFolders.SavedPictures.CreateFolderAsync("MyFolder", CreationCollisionOption.ReplaceExisting);
await KnownFolders.SavedPictures.CreateFileAsync("MyFile.txt", CreationCollisionOption.ReplaceExisting);
But the same lines of code works with ApplicationData.Current.LocalFolder instead of any KnownFolders' locations.
Steps to reproduce the bug
- Create a new "Blank App, Packaged (WinUI 3 in Desktop)" project.
- Add the following lines of code in the myButton_Click event in MainWindow.xaml.cs.
await KnownFolders.SavedPictures.CreateFolderAsync("MyFolder", CreationCollisionOption.ReplaceExisting);await KnownFolders.SavedPictures.CreateFileAsync("MyFile.txt", CreationCollisionOption.ReplaceExisting); - The first line above would throw "The system cannot find the file specified. (0x80070002)".
- The second line above would throw "could not be found. (0x80030002 (STG_E_FILENOTFOUND))".
Expected behavior
Should be able to create a folder or file without any exceptions when the values are valid in any location accessible via the KnownFolders.
Screenshots
NuGet package version
Windows App SDK 1.4.1: 1.4.230913002
Packaging type
Packaged (MSIX)
Windows version
Windows 11 version 22H2 (22621, 2022 Update)
IDE
Visual Studio 2022
Additional context
The same APIs work fine in a UWP project.
The difficulty here is what are you expecting with the behaviour of Application.LocalFolder. The documentation for ApplicationData.Current states: "Provides access to the app data store associated with the app's app package."
So, what is this data store and how does it relate to the various directories in the user profile? Well, let's use a simple application to look at these paths.
#include <Windows.h>
#include <winrt/Windows.Storage.h>
int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int)
{
auto saved_pictures = winrt::Windows::Storage::KnownFolders::SavedPictures();
auto sp_path = saved_pictures.Path();
auto ad = winrt::Windows::Storage::ApplicationData::Current();
auto lf = ad.LocalFolder();
auto lf_path = lf.Path();
return 0;
}
This is a C++ desktop application which is nice and simple. It queries the path of the saved pictures library and then queries the path of the current application directory. First, and most interestingly, if this is run from an unpackaged application, ApplicationData.Current fails with the error 0x80073D54, "The process has no package identity." Already, this would hint at ApplicationData.Current pointing to a different directory than the libraries in the user profile. The saved pictures library ends up being:
Okay, so lets package the application and see how things change. Saved pictures has the same path as above. The application has a package identity so ApplicationData.Current works. But wait:
That path is a little different from the libraries portion of the user profile. So for this package, the full path that this is pointing to is:
Unfortunately, your success case here seems to be a misunderstanding. You are creating directories and files in a completely different location than you think. While this is a non WinUI 3 C++ project, this should be irrelevant in this case. This is how packaged applications work. The pictures library doesn't have permission for packaged applications to access anything under it by default, where the application package data directory does.
Finally, there is a lack of information on how your project is configured. You state that it is packaged, but as the KnownFolders.SavedPictures documentation states, the application manifest must specify the pictures library capability if you want to access it. However, you do not show your Package.appxmanifest file (or AppxManifest.xml file if you are manually using makeappx). Do you have:
selected? If you are manually packaging the application, then you should look for:
<Capabilities>
<!--Other capabilities here-->
<uap:Capability Name="picturesLibrary"/>
<!--Other capabilities here-->
</Capabilities>
If you don't have the pictures library capability enabled, do things change if you enable it?
I wanted to create folders and files within the PicturesLibrary which I'm unable to do with the KnownFolders API. I've added the capability to access PicturesLibrary already but I missed out to post that here. It didn't change anything though.
I have to admit, that is very surprising.
https://github.com/microsoft/WindowsAppSDK/assets/52577874/c8862db3-d9c4-4b60-9112-cada778999d4
With that capability, I have no issues. Yes, I used a WinUI 3 C# project for this. I also followed your instructions in a separate project. I included an extra step of adding the required capability to the manifest. The application is expected to fail without the pictures library capability. Again, it worked without issue. So, can you think of any other possible differences that you forgot to mention? It could also be a difference that you dismissed as unimportant. For example, redirected library paths?
I wonder why it doesn't work for me. I have the latest version (1.4.231115000) of Microsoft.WindowsAppSDK installed and the issue still exists. Also, this works fine for me in a sample UWP app. The issue is only with WinUI3 app. I've noticed that though the app has capabilities added, it doesn't show up in the list of apps that can access the pictures Library in the privacy settings of the PC. I added picturesLibrary capability to a sample UWP app, and it shows up in the list but the WinUI3 app didn't.
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 7 days of this comment.