I have here a cross platform app, which uses DependencyService to get a file path for my log file. This works fine for ApplicationData.Current.LocalCacheFolder.Path, but now the log file should be made accessible to the user. The idea was that the user plugs his device into the PC, copies the log file from it and then send it to me via normal email. (Currently, it is not planned to distribute the app via the store and it is not guaranteed, that the user has an email account setup on his device.)
First, I tried with KnownFolders.DocumentsLibrary, but here I get Access is denied. If I look into the documentation, this folder is not intended for my use. Other locations also doesn't seem to fit.
Is this approach feasible in UWP?
You need to add Capabilities of documentsLibrary to access KnownFolders.DocumentsLibrary
To add go to "Package.appxmanifest" in YourApp.UWP > "Capability" tab and check the capability where you want to store. Example: "Picture Library" or "Removable Storage"
New anser:
I found out, that Access denied only occurs on desktop, not mobile. Afterwards, I found this post, which describes why this does happen. It's because of the permission handling and that I throw away my permissions. There are several possibilites how to handle this situation:
Use a picker to ask the user
Use FutureAccessList
Example:
FolderPicker folderPicker = new FolderPicker();
folderPicker.FileTypeFilter.Add("*");
StorageFolder folder = await folderPicker.PickSingleFolderAsync();
if (folder != null)
{
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
}
StorageFolder newFolder;
newFolder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync("PickedFolderToken");
await newFolder.CreateFileAsync("test.txt");
Use streams instead of paths (for library)
Make a copy of the file and store it into the application data folder
Example:
StorageFolder tempFolder = await StorageFolder.GetFolderFromPathAsync(Path.Combine(ApplicationData.Current.LocalCacheFolder.Path, "YourApp"));
StorageFile tempFile = await tempFolder.CreateFileAsync(Path.GetFileName(pathToAttachment), CreationCollisionOption.ReplaceExisting);
await file.CopyAndReplaceAsync(tempFile);
Old answer:
My current solution is that I offer a button in my app, which calls natively the FolderPicker via DependencyService and only on UWP. With this the user can select the location and I copy the file to this location. Works nicely, despite I wish I didn't had to do something only for one platform.
Related
I need to access random folders somewhere on my local filesystem.
UWP normally has no access to them and the approach with setting "broadFileSystemAccess" does not work sadly.
What would be a good approach to access those folders and the files within in my UWP App? I thought about writing a small WPF App that copies those files from the random folder into a folder that my UWP App would have access to.
Edit: The problem with this is, that I want to set the path once on a new device and it should keep the access for the folder even after reboot. Is that possible with the FilePicker solution? I managed to get the broadFileSystemAccess to work but the problem here is, that on every device you need to enable that first manually for this app. Sadly that is not an option, because this app will run on many customer devices.
I am thankful for any kind of advice.
Kind regards
You can use FileOpenPicker to access local location, for example, useing FileOpenPicker access PictureLibrary. For more information about FileOpenPicke, you can refer this document.
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
// Application now has read/write access to the picked file
this.textBlock.Text = "Picked photo: " + file.Name;
}
else
{
this.textBlock.Text = "Operation cancelled.";
}
I don’t know how you use broadFileSystemAccess capability and causes this unexpected behaivor. Generally, broadFileSystemAccess capabilities can make you be able to access folders using StorageFolder() API, for example:
StorageFile file = await StorageFile.GetFileFromPathAsync(#"D:\test.txt");
For more information about accessing additional locations, you can refer this document
update
There is a way to access local location. You can use MRU and Future-access list. For example, use FileOpenPicker to get a file and save this file to Future-access list and MRU:
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
string mruToken = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file, "20120716");
string faToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(file);
For more information about MRU and Future-access list, you can refer this document.
New to C#/VS, trying to get a listing of files, feel like this has a simple answer but can;t find.
Basically, wanting to get a file listing, tried various methods but for simplicity, why does
var f = Directory.GetFiles(#"C:\");
returns
System.UnauthorizedAccessException: 'Access to the path 'C:\' is
denied.'
Tried running VS as administator, tried on sub folders, tried with sub folders having Everyone with full control permission. Same results.
In order to access an arbitrary folder from your UWP app, the user first needs to provide consent via the FolderPicker dialog:
FolderPicker picker = new FolderPicker();
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
picker.FileTypeFilter.Add("*");
StorageFolder folder = await picker.PickSingleFolderAsync();
var files = await folder.GetFilesAsync();
https://learn.microsoft.com/en-us/uwp/api/Windows.Storage.Pickers.FolderPicker
System.UnauthorizedAccessException: 'Access to the path 'C:\' is denied.'
Rob has said Windows Store apps run sandboxed and have very limited access to the file system in his blog. Access to other locations is available only through a broker process. This broker process runs with the user’s full privileges.
So you could access the folder that mentioned by Stefan Wick with full privileges FolderPicker.
Apps can access certain file system locations by default. Apps can also access additional locations by declaring capabilities.
There are some locations that all apps can access. Such as InstalledLocation LocalFolder.
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
In addition to the default locations, an app can access additional files and folders by declaring capabilities in the app manifest. Such as Pictures Music library.
<Capabilities><uap:Capability Name="musicLibrary"/></Capabilities>
<Capabilities><uap:Capability Name="picturesLibrary"/></Capabilities>
For more, you could refer to File access permissions. And Skip the path: stick to the StorageFile will help you understand uwp file access in depth.
What I need to do:
Save an image file to an exact, specific location when the app is run (Let's say "Z:\test\photo.jpeg").
Additional wanted functionality:
1) Overwrite the file ''Z:\test\photo.jpeg' if it already exists.
2) Skip the write, if the folder 'Z:\test\' doesn't exist.
What I've already tried:
using Windows.Media.Capture.UI;
using Windows.Storage;
CameraCaptureUI camera = new CameraCaptureUI();
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
var targetFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("photo.jpeg", CreationCollisionOption.ReplaceExisting);
if (targetFile != null)
{
await targetFile.DeleteAsync();
await photo.MoveAndReplaceAsync(targetFile);
}
}
Question:
Is there a way to get the variable 'targetFile' to point to a particular location, eg. "Z:\test\photo.jpeg"?
I don't want to use local app data folder, pictures folder, or anything like that. It needs to be this particular location.
Univeral Apps are sandboxed and can only access their on storage folders.
You can grant access to other files using FileOpenPicker or FolderPicker, but you won't have control about what file the user picks for you to write into.
This means you have to make your user pick that exact file for you to store at, otherwise your app can't access that location.
Here's an overview on accessible file locations for UWP apps on MSDN.
I am making a Windows 10 UWP App. As part of this app I need to be able to search inside the User Device's Downloads folder (Not the Apps Downloads folder).
I have created a Folder Picker for the user to be able to choose the downloads folder themselves. However, I need to do this without the user.
Here is My Folder Picker:
FolderPicker picker = new FolderPicker();
picker.FileTypeFilter.Add("*");
picker.ViewMode = PickerViewMode.List;
picker.SuggestedStartLocation = PickerLocationId.Downloads;
StorageFolder folder = await picker.PickSingleFolderAsync();
Is there any way in which I could use something like Folder Picker, but hard-coded so the destination is always set to one place (The Downloads Folder)?
You are not allowed to search the Downloads folder, but if all you want to do is regain access to a file you previously downloaded, you can use the FutureAccessList.
using Windows.Storage.AccessCache;
file = await DownloadsFolder.CreateFileAsync(...);
var token = StorageApplicationPermissions.FutureAccessList.Add(file,
"anything you like goes here");
You probably want to save the token in your app's local storage so you won't forget it.
Use the token to regain access to the file in the future.
file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(token);
I want to download files to Downloads folder and read. it is a root folder like photos and videos.
But Windows.Storage.DownloadsFolder isn't available for phone and I don't see it in KnownFolders like Windows.Storage.KnownFolders.PicturesLibrary;
Also I tried C:\Data\Users\Public\Downloads\ it gives an unauthorized result.
I see some apps has access to it, but how?
You can use a file or folder picker.
I'm not sure if you want the user to chose a file, or if you want to pick a file yourself, but i think the best way to achieve this is using something like:
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.SuggestedStartLocation = PickerLocationId.Downloads;
StorageFile file = await openPicker.PickSingleFileAsync();
or
FolderPicker folderPicker = new FolderPicker();
folderPicker.SuggestedStartLocation = PickerLocationId.Downloads;
folderPicker.PickFolderAndContinue();
To complete the previous answer, it is possible to access such a folder, but only after a first access to it through FolderPicker.
The trick is to use the StorageApplicationPermissions.FutureAccessList. It is what file explorers applications do. It will give you a token that you can save in your IsolatedStorage, so you can later access the Downloads folder directly, thanks to the token.
See there for a walkthrough with StorageApplicationPermissions.mostRecentlyUsedList : http://msdn.microsoft.com/library/windows/apps/hh972603 but the principles are quite the same with FutureAccessList.