How to Delete Files and Application Data Container Values in One Go? - c#

I have a reset function in my app which brings the app back to default state. There for I need to remove the four files I created and remove the settings I created in the ApplicationDataContainer.
This is how I remove the files
try
{
StorageFile file = await localfolder.GetFileAsync("HistoryFile");
if (file != null)
{
await file.DeleteAsync();
}
}
catch
{
//Catch Process
}
Is there a function which removes all the files together? When I tried the following code
localfolder.DeleteAsync()
It removed the LocalState folder along with the files, I jus need to remove the files not the folder.
And is there anyway in which I jus can remove all the values stored in ApplicationDatacontainer in one go? rather than removing them one by one like this?
localSettings.DeleteContainer("exampleContainer");

If you want to remove application data from its local data store, try this.
await Windows.Storage.ApplicationData.Current.ClearAsync(
Windows.Storage.ApplicationDataLocality.Local);

Related

UWP StorageFolder access to the Downloads folder

I have done a ton of research on MSDN and SO but there seem to be a lot of mixed reviews on this topic and no straightforward answer. My UWP app needs to download some items for the user. It seems only logical that this goes into the "downloads" folder instead of Documents or Pictures.
What I gather from my reading is that an application is allowed to access the downloads folder and create files and sub folders within the downloads folder. However, it cannot access other files and folder (not created from your app) without the use of a picker. In this case, I should not need to use a picker because my app is using the and creating the folder for itself. I have also read, there is not need for special capabilities in the Manifest for this to work.
I can confirm that this does in fact work by creating a folder and a file in the downloads folder
StorageFile destinationFile;
StorageFolder downloadsFolder;
try
{
//Create a sub folder in downloads
try
{
downloadsFolder = await DownloadsFolder.CreateFolderAsync("AppFiles");
}
catch (Exception ex)
{
//HERE IS THE ISSUE. I get in here if the folder exists but how do i get it?
}
destinationFile = await downloadsFolder.CreateFileAsync(destination,CreationCollisionOption.GenerateUniqueName);
}
catch (FileNotFoundException ex)
{
rootPage.NotifyUser("Error while creating file: " + ex.Message, NotifyType.ErrorMessage);
return;
}
However, here is the major issue. This code works fine the first time through because the folder does not already exist and it creates it along with the file. Subsequent times through, it fails and throws an exception:
Cannot create a file when that file already exists. (Exception from HRESULT: 0x800700B7)
It does this on the line to create the folder in Downloads folder:
downloadsFolder = await DownloadsFolder.CreateFolderAsync("AppFiles");
The problem is that MSDN states that I cannot use the Collision options of "OpenIfExists" or "ReplaceExisting" which are the two collision options I would need to solve this problem. The two remaining options do no good for me. So, no matter what, it is going to throw an exception if the folder exists.
Then, the thought is that I could just catch the exception, like I am already doing in my snippet above and open the folder if it exists. The problem with this is that the "DownloadsFolder" class does not give any options to get or open a folder, only to create a folder.
So, it seems I can create the folder from my app but I cannot open or get the folder that my app created?
Thanks!
The problem with this is that the "DownloadsFolder" class does not give any options to get or open a folder, only to create a folder.
Actually, When you first run your code, you could create your folder successfully and get the folder instance to create file in this folder. But why you could not get it when it's existed, it's by design.
I believe you have checked the document:
Because the app can only access folders in the Downloads folder that it created, you can't specify OpenIfExists or ReplaceExisting for this parameter.
So, How to get the folder that you created? I will tell you in the following:)
In this case, I should not need to use a picker because my app is using the and creating the folder for itself.
As you said, the first option is to use a picker, but you've said that you do not want to use a picker. Then, I will give you another option.
When you first create the folder successfully, you could add this folder to the FutureAccessList. Then, you could get this folder directly in your code.
I've made a simple code sample for your reference:
StorageFile destinationFile;
StorageFolder downloadsFolder;
try
{
try
{
downloadsFolder = await DownloadsFolder.CreateFolderAsync("AppFiles");
string folderToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(downloadsFolder);
ApplicationData.Current.LocalSettings.Values["folderToken"] = folderToken;
destinationFile = await downloadsFolder.CreateFileAsync("destination.txt", CreationCollisionOption.GenerateUniqueName);
}
catch (Exception ex)
{
if (ApplicationData.Current.LocalSettings.Values["folderToken"] != null)
{
string token = ApplicationData.Current.LocalSettings.Values["folderToken"].ToString();
downloadsFolder = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFolderAsync(token);
destinationFile = await downloadsFolder.CreateFileAsync("destination.txt", CreationCollisionOption.GenerateUniqueName);
}
}
}
catch (FileNotFoundException ex)
{
rootPage.NotifyUser("Error while creating file: " + ex.Message, NotifyType.ErrorMessage);
return;
}

Creating Files and Folders in UWP

Ive looked at at so many stackoverflow posts and articles but still didnt manage to create a file in UWP. In WPF it was really easy but UWP works differently.
I added the following in my manifest file:
<Capabilities>
<uap:Capability Name="documentsLibrary" />
</Capabilities>
Now im not sure what to do next. Inside my documents folder I have a subfolder named "Project Files". I want to create folders and files in there. How is this done in UWP? I really dont understand.
As microsoft states in their docs, its recommenced not to use the documents Library through an UWP app, instead opt for the built in storage unless its absolutely necessary.
There is an easy way to get around that if you use a folder picker
private async void buttonClick(){
FolderPicker folderPicker = new FolderPicker();
folderPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
folderPicker.FileTypeFilter.Add("*");
StorageFolder folder= await folderPicker.PickSingleFolderAsync();
if (folder != null) {
// do Things On Folder
}
else
{
MessageDialog dialog = new MessageDialog("you selected nothing");
await dialog.ShowAsync();
}
}
The above opens up a folder select dialog, it returns the folder the user picked, its the recommended way for accessing locations outside your app's folder.
Here is how to Create a new file in this folder:
string name ="myTitle.txt";
await folder.CreateFileAsync(name, CreationCollisionOption.GenerateUniqueName);
here is how to open and write a file:
try {
StorageFile myFile = await folder.GetFileAsync(name);
await Windows.Storage.FileIO.WriteTextAsync(myFile, "myStringContent");
}
catch (Exception e)
{
Debug.WriteLine("Failure: "+e.Message);
return;
}
remember you can always avoid opening up a dialog if you use the local storage instead, it returns you app's storage folder in one line, like this:
var folder= ApplicationData.Current.LocalFolder;
I believe in UWP using the documents library is neither recommended or permitted. See https://blogs.msdn.microsoft.com/wsdevsol/2013/05/09/dealing-with-documents-how-not-to-use-the-documentslibrary-capability-in-windows-store-apps/
If you side load the app and use the documents library capability the app gets access only to declared file types, not to everything in documents.
See https://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx#special_capabilities
Note that this special capability will not let you pass through app certification in Store, unless you go through some special procedure contacting MS first.
To create folder, use StorageFolder. To create file, use StorageFile.
See https://learn.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files

Trying to delete folders that are either empty, or only have hidden files within

I'm trying to clean up my lightroom folders and have found that sometimes there are hidden files left behind from moving the files from them around.
I did some searching and was able to build this Frankenstein function, but every time it tries to delete an empty folder I get an error saying that the folder is in use by another process....
Basically I am trying to recurs through all of the folders and delete the ones that are empty children, or ones that only have hidden files within. This process should repeat through all of the folders removing their children and eventually the parent if there are no files (or only hidden files) contained therein.
Any help or suggestions would be greatly appreciated!
Cheers!
private static void processDirectory(string startLocation)
{
//For every folder in this folder, recurse into that folder and take a peek...
foreach (var directory in Directory.GetDirectories(startLocation))
{
processDirectory(directory);
//Get a handle to the directory to get files and whatnot from....
DirectoryInfo di = new DirectoryInfo(directory);
FileInfo[] files = di.GetFiles();
//We want to ignore any hidden files in the directory
var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));
//Make sure there are no other files or directories behind this one
if (filtered.Count() == 0 && Directory.GetDirectories(directory).Length == 0)
{
//Okay it's safe, delete it now.
di.Delete();
}
}
}
Well if this weren't bizarre enough, this morning when I ran the code it worked just fine!? My folders have been pruned down to only the ones that actually have photos in them, and life is good.
The one thing that I did have to do is add true to the di.Delete() function. This was because the function was stopping on folders that had hidden files in them.
I am assuming it was something along the lines of what Chris posted above and some latent function was still open from Adobe.
Thanks to everyone that posted a reply!
Cheers!

WinRT create a file if it doesn't exist and know that the file was created

I would like to open a file, and if it does not exist create it, similar to this question
The catch is that if the file was newly created I perform some additional initialization logic.
I can use
await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists)
to open the file if it already exists, but how can I tell if the result of this operation was a newly created file or just opening an existing file? Is there a best practice here or am I stuck looking at the file create date or file size?
Ideally the code would look something like this:
var file = await folder.CreateFileAsync(fileName, CreationCollsionOption.OpenIfExists);
//How can I reliably tell if the file was new?
if (fileIsNew)
await InitializeFile(file);
With using the CreationCollsionOption.OpenIfExists there is no way to tell what's happened other than looking the CreatedDate or the Size of the file.
So I think you are better if you use the GetFileAsync (like in the linked question) and do your initilaize logic in the catch FileNotFoundException branch, because there is no File.Exists in WinRt
However there is a third solution where you enumerate the files in the directory and check for existence by hand:
var files = await folder.GetFilesAsync(CommonFileQuery.OrderByName);
var file = files.FirstOrDefault(x => x.Name == fileName);
if (file == null)
{
file = await GetFilesAsync(fileName);
await InitializeFile(file);
}
Note: in this case potentially you have to prepare to handle race conditions becase it can happen while you are processing the file list somebody creates the file before you (that's why there is no File.Exists method exists)
I had a similar situation where I wanted to determine if an app was running for the first time. Here's how I approached it.
try
{
await ApplicationData.Current.LocalFolder.GetFileAsync(FirstRunFile);
}
catch (FileNotFoundException)
{
isFirstRun = true;
}
if (isFirstRun) {
// Perform necessary initialization here
await ApplicationData.Current.LocalFolder.CreateFileAsync(FirstRunFile);
}

OPEN a Resource.resx file instead of Creating it which overrides the previous Resource.resx file

I start my application from withint Visual Studio 2010.
I add then some files into my application and each file type`s icon like icon from doc,docx,xls,pdf etc are added as String/Bitmap key/value pair to my IconImages.Resx file via
private void DumpTempResourceToRealResourceFile(IDictionary<String, Bitmap> tempResource)
{
using (ResXResourceWriter writer = new ResXResourceWriter("IconImages.Resx"))
{
foreach (KeyValuePair<String,Bitmap> item in tempResource)
{
writer.AddResource(item.Key, item.Value);
}
writer.Generate();
}
}
When the icons are added to the resource I close the application.
Then I start my application again with VS 2010 and add some files within my document application. The file types are written again to my IconImages.Resx.
Then I close my application and check the IconImages.Resx file under the \bin\ folder and the previous saved images are gone and I have new/different ones now.
Why can I not say OPEN a .resx file and append stuff to it? Everytime I create a ResourceWriter object with the same name "IconImages.Resx" I overwrite the previous added stuff and thats stupid.
How can my IconImages.Resx file stay alive over an application session without being overwritten by other stuff I add?
I haven't used ResXResourceWriter, but usually *Writer classes simply write a data file from scratch.
If you want to "append" new data you would typically have to use a *Reader class to deserialise the existing data into memory, then merge/add in any new data you wish to, and use a *Writer object to then write the resulting data back out. Take a look at ResXResourceReader to see if it supports what you need to do this.
I am having now a lookup table "FiletypeImage" with the filetype ".docx" and the raw binary data aka blob. This table gets retrieved in my documentService and cached in a static variable. with a Get and Add method which are called by my DocumentListViewModel. Its very fast thx to sqlite :)

Categories