Creating a file/folder in UWP - c#

first of all I really hope I'm not asking already answered question, I did my research on stack overflow and beyond and so far didn't find answer to my question.
I finally accomplished that my Universal windows (10) app makes a project folder for user, inside LocalState folder, but its fine as long as it stays there. Now, I'm trying to generate some simple text file and save in "Project" folder, example path: LocalState\Project1\example.txt.
I tried with following code:
StorageFolder mapa_projekta = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await mapa_projekta.CreateFileAsync("sample.txt");
But it only saves to LocalState directory, maybe there is simple solution of adding path to the sub folder, but so far I didn't succeed in that.
Sorry for my poor english and thanks for all your time
Wish you all nice day

First, we can make the project folder:
StorageFolder rootFolder = ApplicationData.Current.LocalFolder;
var projectFolderName = "Project1";
StorageFolder projectFolder = await rootFolder.CreateFolderAsync(projectFolderName, CreationCollisionOption.ReplaceIfExisting);
Then, you can create your file within your subfolder:
StorageFile sampleFile = await projectFolder.CreateFileAsync("sample.txt");

Related

UWP Access Denied to StorageFile

I'm getting access denied when using
StorageFile.GetFileFromPathAsync(filePath)
From other posts and some documentation that I read UWP can only access to video lib, videos, (profile related folders) when declared in the Package.appxmanifest etc...
With FilePicker I have no problem accessing these locations, but the StorageFile.GetFileFromPathAsync was to automatically load those files into a list when the page loads.
How can I use this function to load files outside known folders video lib, videos, etc.
You can only use this method to access files on those safe paths UWP apps have access to. If you get access to another location via a file or folder picker, you must cache access to it using Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList. This API allows you to store an existing instance of StorageFile or StorageFolder and gives you a "token", which is a string by which you can later access the selected StorageItem again.
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
string faToken = StorageApplicationPermissions.FutureAccessList.Add(file);
}
Now that the file is in FutureAccessList, you can later retrieve it:
StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(faToken);
Items stored in FutureAccessList survive even when the app is closed and reopened so it is probably the ideal solution for your use case. However, keep in mind the FutureAccessList can store at most 1000 items (see Docs), and you must maintain it - so if you no longer need an item, make sure you delete it, so that it does not count towards the limit anymore.
The second solution would be to declare the broadFileSystemAccess capability. This is however a restricted capability and your app must have a good reason to use it.

How can I browse through the neighboring files in my Windows 10 App?

I try to make a photo editor/viewer as the Windows 10 App. I let the user to open an image file by FileOpenPicker. The program also should be able to browse other images from the same folder as the selected file (e.g. by previous and next buttons), but there is the problem. I even can't get file names of these images.
All the methods I have tried just return null...
// File picker to let user select the image file - works OK
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".jpg");
var file = await picker.PickSingleFileAsync();
// These methods to get neighboring files do not work
// 1. using Directory.GetFiles - it returns empty string
string filePaths[] = Directory.GetFiles(Path.GetDirectoryName(file.Path));
// 2. using GetParentAsync - it returns null instead of file's parent folder
var folder = await file.GetParentAsync();
var files = await folder.GetFilesAsync();
So, how can I browse through the other files from the same folder as the already opened file?
I have found I can use a FolderPicker to get access to given folder, but that would be a very silly solution if the user need to go through two pickers (one for the image file and another for the actual file's folder).
EDIT: After I checked Removable Storage and Picture Library in App Manifest, the GetParentAsync started to work for USB drives, but when I open an image file from any local drive it still returns null. Why it does not work for local HDD drives, which are the logical storage device for large amount of photos? Storing data only to user folders on small SSD system drive or USB drive is so limiting.
Basically, If user pick a 'File' by FilePicker, you have the rights only for the 'File'. Not for parent folder. (If you have access rights for picture library and the file is located at the library, you can access the folder. But, the rights comes from library access, not from the file.)
This is a design of WinRT's file accessing rule via FileBroker.. It's hard to overcome.
My recommendation (and many of storeapp picture viewer choose this way, including my app PICT8) is, Ask user to set the folder that the user mainly used to keep the image files by using FolderPicker.
You can keep the access rights for the folder by using FAL or MRU. Instead of using FilePicker, You can show the list of files to your user.
StorageApplicationPermissions class
And...My answer for another thread may help you also: Access all files in folder from FileActivated file
You got a StorageFile from the FileOpenPicker. You can get the containing folder with the GetParentAsync method and then call GetFilesAsync to get the files inside the folder.
var folder = await file.GetParentAsync();
var files = await folder.GetFilesAsync();
var next = files.SkipWhile(x => x.Name == file.Name)
.Skip(1)
.First();
As you can see you can get the next file inside the folder be skipping ech file until you find your current. Then skip it and take the first after your file.
I think it would better to order the files before you acccess them by calling OrderBy respectivly OrderByDescending on the files result.
You are able to pass a lambda expression to select an property or value for sorting.

Loading TXT file in Windows Phone 8.1

Thanks to the below link, I've found out how to load a TXT file into my Windows Phone 8.1 app. My question is specifically tied to WHY my code doesn't work. (My code begins after link to the other StackOverflow question).
This is the same question, with a working answer.
Read text file in project folder in Windows Phone 8.1 Runtime
I set the StorageFile as the relative location of the file on the phone. I then try and use that location to open a StreamReader. This small snippet compiles fine, however on execution, encounters a runtime error, and "firstFile" is empty/null.
const string filename = "FileToRead.txt";
StorageFile firstFile = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
using (StreamReader streamFirstFile = new StreamReader(await firstFile.OpenStreamForReadAsync()))
{
loadText_Button.Text = await streamFirstFile.ReadToEndAsync();
}
To hopefully further clarify this specific question, are the following two lines of code the same, and if not, how am I using it wrong?
ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
StorageFile.GetFileFromApplicationUriAsync(new Uri(#"ms-appx:///Assets/FileToRead.txt"))
I even tried to set it as follows:
ApplicationData.Current.LocalFolder.GetFileAsync(String.Format("{0}{1}", "Assets/", fileName);
Thank you all in advance.
If you want to read a file from your package then you should refer to Package.Current.InstalledLocation, not LocalFolder. You should also check if your resource has Build Action set to Content.
You can access your file in two ways - either getting it from InstalledLocation folder:
StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(#"Data\" + fileName);
or by Uri:
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(#"ms-appx:///Data/"+fileName));
Few notes:
files in package are read-only,
you can also access files in shared projects by providing its name before folder name
watch out for Build Action - some files are by default set as Content by VS and some not.
You can also find some useful information at this post.
A note for the unwary.
If the name of the file you placed in your Assets folder ends with ".json", the file won't be accessible from your code using the above given function calls. Simply rename the file so that it ends with ".txt".
I would have made this a comment but I don't have the required reputation.

How to get a StorageFolder from an user-friendly (localized) path?

How to get a StorageFolder from a user-friendly (localized) path?
Folders can have a user-friendly (localized) name. The name can be read via:
StorageFolder.DisplayName
Example: The Folder 'C:\Users' is shown on a 'German' Windows as 'C:\Benutzer'.
I would like to get the StorageFolder from a user-friendly path like the Windows Explorer. However, calling the following method throws an exception:
var folder = await StorageFolder.GetFolderFromPathAsync(#"C:\Benutzer");
Is there some support in WinRT API to achieve this?
Edit: I'm not explicitly answering the localised part of your question, but it's entirely possible that you're falling foul of a permissions issue that I describe below.
It's not possible in WinRT to access the file system** without it being user initiated.
The mechanism they have in WinRT for what you're describing is to ask the user to pick the location via a folder picker, then to add that chosen folder to the FutureAccessList for programmatic access later.
StorageFile folder = await folderPicker.PickSingleFolderAsync();
folderToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(folder);
//Keep this folder token to access the folder programmatically later
You can access that folder later using the following.
StorageFolder folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(folderID);
Note that there's absolutely no exception handling in this example. Check the links (particularly the latter) for more details.
** As in your example, however there are standard folder / file resources you can access without this.
you can get the StorageFolder located into app install path - Package.Current.InstalledLocation.Path by specifying the path manually, for example you downloaded a folder with subfolders and you want to get a file from there, you'll use:
StorageFolder customAppFolder = await StorageFolder.GetFolderFromPathAsync(Package.Current.InstalledLocation.Path + #"\yourFolder\yourSubfolder");
now you can iterate files in that subfolder:
IReadOnlyList<StorageFile> filesInFolder =await appFolder.GetFilesAsync();
foreach (StorageFile file in filesInFolder){
Debug.WriteLine(file.Name);
}

StorageFile store = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(#"~\Assets\KuchBhi.pdf");

Before trying to run the following code for a metro app
StorageFile store = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(#"~\Assets\KuchBhi.pdf");
I anticipated that the compiler would throw an exception since there is no file named as KuchBhi.pdf in the assets folder, but that is not what happens, instead the machine just jams with a black screen and no further execution happens...
Can anyone tell me what could be the problem and how to resolve it.
Thank You

Categories