I'm making a Windows 10 Universal App and I want the user to pick a folder to save the document files for the App. The path for this folder is saved to ApplicationData.Current.RoamingSettings.Values.
Here's the code:
On first Start:
var folderPicker = new FolderPicker { SuggestedStartLocation = PickerLocationId.ComputerFolder };
StorageFolder folder = await folderPicker.PickSingleFolderAsync();
StorageFolder homeFolder = await folder.CreateFolderAsync("App1 Data", CreationCollisionOption.OpenIfExists);
var save = ApplicationData.Current.RoamingSettings.Values;
save["HomeFolder"] = homeFolder.Path;
When HomeFolder is set:
string dir = save["HomeFolder"].ToString();
try
{
StorageFolder homeFolder = await StorageFolder.GetFolderFromPathAsync(dir);
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
The thrown Exception in the second code sample is:
System.UnauthorizedAccessException: access denied (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
So my question is, how do you use the GetFolderFromPathAsync function correctly?
I checked all strings for the paths, they are all right, even
StorageFolder.GetFolderFromPathAsync(storageFolder.Path);
doesn't work.
Do you know a solution?
Use the StorageFile directly rather than converting to a path.
To store the file returned from the file picker for later use save the StorageFile in the AccessCache classes FutureAccessList or MostRecentlyUsedList. The path doesn't include the spermissions needed to open the file. The StorageFile carries the permissions and grants access to the file.
I discussed this in more detail in my blog entry Skip the path: stick to the StorageFile
Related
Here is my code........
public MediaPlaybackItem GetMediaPlaybackItemFromPath(string path)
{
//StorageFile file = await StorageFile.GetFileFromPathAsync(path);
var source = MediaSource.CreateFromUri(new Uri(path));
return new MediaPlaybackItem(source);
}
If I use this method I cannot play music. But if I try this I can play music.
public async Task<MediaPlaybackItem> GetMediaPlaybackItemFromPathAsync(string path)
{
StorageFile file = await StorageFile.GetFileFromPathAsync(path);
var source = MediaSource.CreateFromStorageFile(file);
return new MediaPlaybackItem(source);
}
Whats the problem with this? I am using mediaplaybacklist for MediaPlayer.Source . How can I get proper MediaSource using my first method? Help me please.
You could not pass file path parameter to CreateFromUri directly. In general, the Uri parameter is http protocol address such as http://www.testvideo.com/forkvideo/test.mp4. But we could pass the file path with uwp file access uri scheme.
For example:
Media file stored in the installation folder.
ms-appx:///
Local folder.
ms-appdata:///local/
Temporary folder.
ms-appdata:///temp/
For more you could refer this document.
I want to open a text file with Open File Picker and show in a RichEditBox, but when I select the file and push Ok, Visual Studio show "Access Denied", I want to know how to solve this please, there is my code:
var picker = new FileOpenPicker();
picker.ViewMode = PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
picker.FileTypeFilter.Add("*");
picker.FileTypeFilter.Add(".txt");
picker.FileTypeFilter.Add(".text");
picker.FileTypeFilter.Add(".bat");
picker.FileTypeFilter.Add(".js");
picker.FileTypeFilter.Add(".vbs");
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile filepath = await StorageFile.GetFileFromPathAsync(file.Path);
string text = await FileIO.ReadTextAsync(filepath);
RichEditBox1.Document.SetText(Windows.UI.Text.TextSetOptions.None, text);
}
You don't need to call StorageFile.GetFileFromPathAsync(file.Path) since you already have this StorageFile in the file variable returned from PickSingleFileAsync:
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
string text = await FileIO.ReadTextAsync(file);
RichEditBox1.Document.SetText(Windows.UI.Text.TextSetOptions.None, text);
}
The unnecessary GetFileFromPathAsync probably throws an AccessDenied error since the FileOpenPicker provides access only through the returned StorageFile and doesn't give direct access to the file through its path. This behavior is version dependent and new versions of Windows 10 will allow more direct access through file system API (see the Build 2017 talk UWP Apps file access improvements
I have to read the text content from an .txt file, this file is located in app installed folder, in a subfolder, according to Microsoft docs, I am doing it like this:
private async void readMyFile()
{
// Get the app's installation folder.
StorageFolder appFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
// Get a file from a subfolder of the current folder by providing a relative path.
string txtFileName = #"\myfolder\myfile.txt";
try
{
//here my file exists and I get file path
StorageFile txtfile = await appFolder.GetFileAsync(txtFileName);
Debug.WriteLine("ok file found: " + txtfile.Path);
//here I get the error
string text = await FileIO.ReadTextAsync(txtfile);
Debug.WriteLine("Txt is: " + text);
}
catch (FileNotFoundException ex)
{
}
}
the error is:
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.ni.dll
exception file not found: System.IO.FileNotFoundException: The filename, directory name, or volume label syntax is incorrect. (Exception from HRESULT: 0x8007007B)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Smadshop.MainPage.<testExistsFile>d__8.MoveNext()
Have to notice that if I use the file without subfolder everything is working fine.
you can do it in other way, using URI :
using Windows.Storage;
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync("ms-appx:///file.txt");
So in your case it will be:
StorageFile txtfile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///myfolder/myfile.txt"));
I think you need to use:
string txtFileName = #".\myfolder\myfile.txt";
The dot in the filename represents the current folder. In you want to specify using relative paths, then #"\myfolder\myfile.txt" is not correct.
GetFileAsync will take relative path in form folder/fileName. You can also get folder first and than file or use GetItemAsync
StorageFolder appFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
// Get a file from a subfolder of the current folder
// by providing a relative path.
string image = #"Assets\Logo.scale-100.png";
var logoImage = await appFolder.GetFileAsync(image);
#"\myfolder\myfile.txt"; if its a network path should be #"\\myfolder\myfile.txt"; If its a local file it needs a drive letter ie.#"c:\myfolder\myfile.txt";
However the documentation for GetFileAsync shows a file in a subfolder would be #"myfolder\myfile.txt"
When you use a filename without a subfolder it will look in the current folder.
I'm attempting to copy a file from the installed location of my Windows 8 app to it's local storage. I've been researching around and trying to do this to no avail. This is what I have come up with so far but I'm not sure where I'm going wrong.
private async void TransferToStorage()
{
try
{
// Get file from appx install folder
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
StorageFile temp1 = await installedLocation.GetFileAsync("track.xml");
// Read the file
var lines = await FileIO.ReadLinesAsync(temp1);
//Create the file in local storage
StorageFile myStorageFile = await localFolder.CreateFileAsync("track_iso.xml", CreationCollisionOption.ReplaceExisting);
// Write to it
await FileIO.WriteLinesAsync(myStorageFile, lines);
}
catch (Exception)
{
}
}
Any ideas?
Solved it myself. Here is the method for anyone else that encounters this question / problem:
private async void TransferToStorage()
{
// Has the file been copied already?
try
{
await ApplicationData.Current.LocalFolder.GetFileAsync("localfile.xml");
// No exception means it exists
return;
}
catch (System.IO.FileNotFoundException)
{
// The file obviously doesn't exist
}
// Cant await inside catch, but this works anyway
StorageFile stopfile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///installfile.xml"));
await stopfile.CopyAsync(ApplicationData.Current.LocalFolder);
}
No reason to read all the lines and write it to another file. Just use File.Copy.
I have an image file I get from the picker. I save it as 'me.png' in:
Windows.Storage.ApplicationData.Current.LocalFolder
If I perform the action again to try to overwrite the old file with a new one the app crashes with:
An exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll but was not handled in user code
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
If there is a handler for this exception, the program may be safely continued.
The code I'm using to overwrite the file is:
await file.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, "me.png", Windows.Storage.NameCollisionOption.ReplaceExisting);
Any idea why this is happening? It's crashing on that line of code second time round. If I change the collision option to GenerateUniqueName it works fine so it seems to be a problem overwriting the file.
Update:
Full code
localSettings.Values["me_image_path"] = "Asssets/pinkBackground.png";
tile.BackgroundImage = localSettings.Values["me_image_path"];
var picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.ViewMode = PickerViewMode.Thumbnail;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
StorageFile file = await picker.PickSingleFileAsync();
if (file == null) return;
await file.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, "me.png", Windows.Storage.NameCollisionOption.ReplaceExisting);
localSettings.Values["me_image_path"] = "ms-appdata:///local/me.png";
tile.BackgroundImage = localSettings.Values["me_image_path"];