Windows UWP C# delete folder - c#

When I try to delete a folder I get the following error:
Exception thrown: 'System.UnauthorizedAccessException' in mscorlib.ni.dll
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
The whole block of code is here:
StorageFolder folder;
try
{
folder = await ApplicationData.Current.LocalFolder.GetFolderAsync("images");
await folder.DeleteAsync();
StorageFolder new_images = await ApplicationData.Current.LocalFolder.CreateFolderAsync("images", CreationCollisionOption.ReplaceExisting);
}
catch (FileNotFoundException ex)
{
StorageFolder new_images = await ApplicationData.Current.LocalFolder.CreateFolderAsync("images", CreationCollisionOption.ReplaceExisting);
}
The error occurs on this line:
await folder.DeleteAsync();
I'm guessing the issue comes when I add a bunch of images from the images folder like so:
tmp.Source = new BitmapImage(new Uri("ms-appdata:///local/images/image_" + ring.Name + ".jpg", UriKind.Absolute));
It could also be when I save the image:
try {
StorageFile file = await image_folder.CreateFileAsync("image_" + id + ".jpg", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteBytesAsync(file, responseBytes);
} catch (System.Exception)
{
}
If the issue comes because it is reading it and I try to delete the folder, how can I make it work, I honestly don't know what to do here.

Exception thrown: 'System.UnauthorizedAccessException' in mscorlib.ni.dll
I noticed that you were trying to save the image using FileIO.WriteBytesAsync() method, I couldn't see how you load the image file to Byte array. The most possible reason is "forgot to dispose of the stream after opening it to load image data"
This is the way I load an image and save to LocalFolder:
private async Task<byte[]> ConvertImagetoByte(StorageFile image)
{
IRandomAccessStream fileStream = await image.OpenAsync(FileAccessMode.Read);
var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0));
await reader.LoadAsync((uint)fileStream.Size);
byte[] pixels = new byte[fileStream.Size];
reader.ReadBytes(pixels);
return pixels;
}
private async void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
var uri = new Uri("ms-appx:///images/image.jpg");
var img = await StorageFile.GetFileFromApplicationUriAsync(uri);
byte[] responseBytes = await ConvertImagetoByte(img);
var image_folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("images", CreationCollisionOption.OpenIfExists);
StorageFile file = await image_folder.CreateFileAsync("image_test.jpg", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteBytesAsync(file, responseBytes);
tmp.Source = new BitmapImage(new Uri("ms-appdata:///local/images/image_test.jpg", UriKind.Absolute));
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}

It may sound strange but at times authorization type of issues occur when we don't start our IDE as an administrator. Which is done by right clicking on the IDE (Visual Studio) icon and then select 'Run as Administrator'
Try this if it resolves your issue.

You need to use lock to be sure that file or folder will not be modified while it using in another thread. Since you are using await I would suggest to take a look at this - https://github.com/bmbsqd/AsyncLock/
You can get more info about thread sync here - https://msdn.microsoft.com/ru-ru/library/ms173179(v=vs.80).aspx

Related

how to get Bytes of a file for sending in UWP?

I'm a newbie in UWP and i want to open a file of any type and transmit the bytes of it to the reciever. forexample for a jpg file i wrote this code:
// Create FileOpenPicker instance
FileOpenPicker fileOpenPicker = new FileOpenPicker();
// Set SuggestedStartLocation
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
// Set ViewMode
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
fileOpenPicker.FileTypeFilter.Clear();
fileOpenPicker.FileTypeFilter.Add(".jpg");
// Open FileOpenPicker
StorageFile file = await fileOpenPicker.PickSingleFileAsync();
byte[] bytesRead = File.ReadAllBytes(file.Path);
string Paths =
#"C:\\Users\zahraesm\Pictures\sample_reconstructed.jpg";
File.WriteAllBytes(Paths, bytesRead);
the two last lines are for writing the bytes into a file supposing in the receiver. However i keep getting the following exception:
System.InvalidOperationException: 'Synchronous operations should not be performed on the UI thread. Consider wrapping this method in Task.Run.'
Try this Code.
try {
FileOpenPicker openPicker = new FileOpenPicker {
ViewMode = PickerViewMode.Thumbnail,
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
FileTypeFilter = { ".jpg", ".jpeg", ".png" }
};
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null) {
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read)) {
var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0));
var LoadReader = await reader.LoadAsync((uint)fileStream.Size);
byte[] pixels = new byte[fileStream.Size];
reader.ReadBytes(pixels);
}
}
} catch (Exception ex) {
}
consider wrapping last operation in Task.Run()
await Task.Run(()=>{
byte[] bytesRead = File.ReadAllBytes(file.Path);
string Paths =
#"C:\\Users\zahraesm\Pictures\sample_reconstructed.jpg";
File.WriteAllBytes(Paths, bytesRead);
});
You should directly read the bytes from the StorageFile returned from your FilePicker, lest you end up with File permission errors in the future.
StorageFile file = await fileOpenPicker.PickSingleFileAsync();
var buffer = await FileIO.ReadBufferAsync(file);
byte[] bytes = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(buffer);
You should also use await FileIO.WriteBytesAsync(targetFile, myBytes) to write.
Unless you have broadFileSystemAccess in your package Manifest, you should generally avoid using the System.IO API unless you know your application explicitly has permission to access files in that area (i.e., your application's local storage), and instead use Windows.Storage API's
Check MSDN for File Access Permissions for UWP apps for more information on file permissions.
And if you do use System.IO, always perform the work on the background thread via await Task.Run(() => { ... }

windows 10 mobile camera

I'm trying to use the camera in a Windows 10 Mobile App but an error is occurring when I take the picture and try to show it on the screen.
Here's the code:
CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200);
StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo == null)
{
// User cancelled photo capture
return;
}
StorageFolder destinationFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("ProfilePhotoFolder", CreationCollisionOption.OpenIfExists);
await photo.CopyAsync(destinationFolder, "ProfilePhoto.jpg", NameCollisionOption.ReplaceExisting);
await photo.DeleteAsync();
IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap.Convert(softwareBitmap,
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied);
SoftwareBitmapSource bitmapSource = new SoftwareBitmapSource();
await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);
imageControl.Source = bitmapSource;
The exception message:
An exception of type 'System.IO.FileNotFoundException' occurred in
System.Private.CoreLib.dll but was not handled in user code
Additional information: The system cannot find the file specified.
(Exception from HRESULT: 0x80070002)
If there is a handler for this exception, the program may be safely continued."
Someone can help me with this?
This is because you deleted the photo but then trying to read the photo which has just deleted, so the exception "FileNotFound" will throw. Please remove the following code line it will work.
await photo.DeleteAsync();
But I think what you really want to do is to delete the photo which is got from the CameraCaptureUI, and then read the photo from the local folder which has already copied. In that case, code should be as followings:
await photo.CopyAsync(destinationFolder, "ProfilePhoto.jpg", NameCollisionOption.ReplaceExisting);
await photo.DeleteAsync();
StorageFile newphoto = await destinationFolder.GetFileAsync("ProfilePhoto.jpg");
IRandomAccessStream stream = await newphoto.OpenAsync(FileAccessMode.Read);

GetFolderFromPathAsync function access denied

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

Copy file from app installation folder to Local storage

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.

System.Runtime.InteropServices.COMException occurred in mscorlib.ni.dll but was not handled in user code

I am developing a windows application in 8.1 and I am getting a following error.
my application includes a procedure in which I will be moving a file from local storage to SD card.
My code is as follows
namespace MoveFile
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private async void btnCreateFolder_Click(object sender, RoutedEventArgs e)
{
await ReadFile();
//Error is showing here
**await WriteToFile();
}
public async Task WriteToFile()
{
// Get the text data from the textbox.
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(this.txtSafakCount.Text.ToCharArray());
//I got the error in this line.....showing interopservice exception
** StorageFolder knownFolder = await KnownFolders.RemovableDevices.CreateFolderAsync("bdfbdfb", CreationCollisionOption.ReplaceExisting);
StorageFolder sdCard = (await knownFolder.GetFoldersAsync()).FirstOrDefault();
// Create a new file named DataFile.txt.
var file = await sdCard.CreateFileAsync("kaaaaammmmfewfwmHoJa.txt", CreationCollisionOption.ReplaceExisting);
// Write the data from the textbox.
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
public async Task ReadFile()
{
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
// Get the DataFolder folder.
var dataFolder = await local.GetFolderAsync("DataFolder");
// Get the file.
await dataFolder.CreateFileAsync("DataFile.txt", CreationCollisionOption.ReplaceExisting);
var file = await dataFolder.OpenStreamForReadAsync("DataFile.txt");
// Read the data.
using (StreamReader streamReader = new StreamReader(file))
{
this.txtSafakCount.Text = streamReader.ReadToEnd();
}
}
}
}
}
I want to know why this exception occurred and how it can be resolved.
Thanks in advance.
You are doing it wrong - first you should get SD card, then create folder. As the name KnownFolders.RemovableDevices says devices (not single device) - so you get the first of them as SD card (note that Universal Apps are not only for phones). So the working code can look like this:
// first get the SD card
StorageFolder sdCard = (await KnownFolders.RemovableDevices.GetFoldersAsync()).FirstOrDefault();
// then perform some actions - create folders, files ...
StorageFolder myFolder = await sdCard.CreateFolderAsync("bdfbdfb", CreationCollisionOption.ReplaceExisting);
Note also that you also need to add Capabilities in package.appxmanifest file, and Declarations if you want to use files (File Type Associations).
You will also find more help at MSDN.

Categories