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);
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.
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.
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 need to create a file in the downloads folder for a UWA on Windows 10 and copy the content of an existing file into it. I use the following code:
StorageFile cleanFile = await Windows.Storage.DownloadsFolder.CreateFileAsync(cleanFileName);
await file.CopyAndReplaceAsync(cleanFile);
This works ok, but the folder the file is stored is this:
C:\Users\MyUser\Downloads\e15e6523-22b7-4188-9ccf-8a93789aa8ef_t8q2xprhyg9dt!App\WordComment-clean.docx
I assume this is some type of Isolated Storage. But really, that is not what I need. Since the user can't see the file like this.
From MSDN:
User’s Downloads folder. The folder where downloaded files are saved by default.
By default, your app can only access files and folders in the user's Downloads folder that your app created. However, you can gain access to files and folders in the user's Downloads folder by calling a file picker (FileOpenPicker or FolderPicker) so that users can navigate and pick files or folders for your app to access.
If you don't use a file picker, you are saving the file in your app folder in Downloads.
Souce
Using the Download folder
For using the download folder, the user needs to select the download folder manually.
FolderPicker picker = new FolderPicker { SuggestedStartLocation = PickerLocationId.Downloads };
picker.FileTypeFilter.Add("*");
StorageFolder folder = await picker.PickSingleFolderAsync();
if (folder != null) {
await folder.CreateFileAsync("Hello1.txt");
}
I hope this can help you.
Try this:
await file.CopyAndReplaceAsync(cleanFile);
await file.RenameAsync("the name you want")
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.