Windows 10 UWP App XElement.Save() "Access is denied" exception - c#

I'm writing a Windows 10 UWP App, and I'm hitting a snag. I have a Settings.xml in the root of the app folder that I will use to store the DB connection information, as well as a few ancillary settings. I can load the XML fine, and my function to edit works (I can extract the XML through debug and see the changes). My problem comes when trying to write the edited file. I understand that I don't have direct access to the file system with UWP, however I've tried several different methods I've found online to work within my constraints and still can't find one that works. I always come back with an "Access is denied" error in some form or another. Here is a snippet of what my Save function looks like right now. Any help would be greatly appreciated.
try
{
XElement xmlSettings = XElement.Load(uri: "Settings.xml");
XElement xmlNode;
//Do Stuff (clipped for brevity).
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(desiredName: "Settings.xml", options: CreationCollisionOption.ReplaceExisting);
Stream stream = await file.OpenStreamForWriteAsync();
xmlSettings.Save(stream);
Error = "";
}
catch (Exception e)
{
Error = "SaveSettings";
}

I added an xml file to my solution (in the root) and copy pasted your code.
It runs the first time, but gets the exception the second time. The reason is that your stream is not closed. You should use it with using:
using (Stream stream = await file.OpenStreamForWriteAsync())
{
xmlSettings.Save(stream);
}
With this change the code worked even the second time.

Related

UWP StorageFile.CopyAsync() Throwing Error: "Value does not fall within the expected range."

I am trying to overwrite a file with a new version inside of an AppData sub-directory.
Current process is that the user has to select the File to overwrite, and the folder directory it sits in separately so that I can add them to the future access list. Later on the user can select from a collection of images, and it's at that point that it needs to copy and overwrite the destination file. The code I've tried to do this is as follows:
// lets try to copy file to wallpaper default location.
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
var faToken = localSettings.Values["WallpaperStorageFileFAToken"] as string;
var faTokenFolder = localSettings.Values["WallpaperStorageFolderFAToken"] as string;
var destinationFile = await LoadExistingFileSelection(faToken);
var destinationFolder = await LoadExistingFolderSelection(faTokenFolder);
StorageFile movedFile = null;
try
{
movedFile = await imageFile.CopyAsync(destinationFolder, destinationFile.Name, NameCollisionOption.ReplaceExisting);
}
catch (Exception genEx)
{
//
}
The Fa tokens are taken after an FileOpenPicker is used by the User to get the StorageFile and a FolderPicker used to get the StorageFolder for the directory of the destination.
LoadExistingFolderSelection and LoadExistingFileSelection use the following bits of code to get the StorageFiles and StorageFolder
await StorageApplicationPermissions.FutureAccessList.GetFileAsync(faToken);
and
await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(faFolderToken);
The issue is that this line:
imageFile.CopyAsync(destinationFolder, destinationFile.Name, NameCollisionOption.ReplaceExisting);
Throws this error:
"Value does not fall within the expected range."
and that's it, literally nothing else, any thoughts would be great.
Backslashes... Honestly this is one of those moments in you're development career where you just sit there and sigh, because it's just so dumb.
So I could happily retrieve the image I wanted to copy absolutely fine into a StorageFile object, with a path that contained 1 additional backslash that the Windows OS File Explorer wouldn't have batted an eye lid about.
No problem so far, great proceed to then run a copy operation against that, and suddenly you get the
“Value does not fall within the expected range.”
exception, argue-ably one of the least helpful exceptions relating to a problem with a file path that I've seen.
So there you have it, backslashes, really carefully examine the Path property. Hindsight. Normally I would just remove that question because this answer isn't particularly any kind of great revelation. But I figure it can stay as a warning about the fearsome backslash and UWP's Storage API.

C# Access Denied when trying to Copy and XML file

c# question here. I keep getting access is denied when trying to move an xml file. I know the problem is that it is creating a temporary XML file with no admin privileges which its needs, and I have tried editing the appmanifest with the require admin = true line to no avail. I have also tried setting the permissions outside the program and running visual studio as an admin.
Link to the pastebin code.
https://pastebin.com/M7dRTXHY
I actually got an answer for this using completely different code yesterday but my teacher said I must do it this way. I have spent hours trying to debug this and am losing my mind.
It is a windows 10 phone application as well, not sure if that changes anything.
I realise there is a million and one other questions similar to this but I cannot get anything to work.
This is the exact tutorial I was following taken straight from my course.
Use the StorageFile for the move/copy/delete etc operations:
private async void Grid_Loading(FrameworkElement sender, object args)
{
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
StorageFolder installedLocation = package.InstalledLocation;
StorageFolder targetLocation = ApplicationData.Current.LocalFolder;
var targetFile = await installedLocation.GetFileAsync("Contacts.xml");
await targetFile.MoveAsync(targetLocation);
TARGETFILEPATH = ApplicationData.Current.LocalFolder.Path.ToString() + "\\Contacts.xml";
loadContacts();
}
more on StorageFiles here.

Access to path denied but the file has no restrictions

I'm new to C# and not an expert at programming in general, but I can't seem to figure out what is causing this problem. I am letting the user pick a XML file and then I want to read it's contents. This is in C# making a universal windows 10 app
This is the error I'm getting:
An exception of type 'System.UnauthorizedAccessException' occurred in
mscorlib.ni.dll but was not handled in user code
Additional information: Access to the path 'C:\temp\file.xml' is
denied.
public async static void pickFile()
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.List;
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
openPicker.FileTypeFilter.Add(".xml");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
var t = Task.Run(() => { reset(file.Path); });
}
}
then
private static void reset(string path)
{
String LocationDatafilename = path;
XmlReaderSettings settings = new XmlReaderSettings();
XmlReader reader = XmlReader.Create(LocationDatafilename, settings);
XmlDocument LocationDataXml = new XmlDocument();
LocationDataXml.Load(Globals.reader);
}
When I get to XmlReader.Create that's when I'm getting the error. When I look for the cause, the only thing I find is due to permissions, but that isn't the case. Any help would be appreciated. Thanks.
You need to operate on the StorageFile directly, since your app doesn't have permissions to directly read the user's files. You can either use the WinRT XML API or you can keep using the .NET API and use the stream-based Create function instead of the one that takes a file name.
Run sysinternal's ProcMon app, and at the same time run your application. Find the file in the procmon capture, and in the CreateFile entry, you'll find the creation Disposition. This will give you a clue why the creation failed. Also, select the "User" column to show the user performing the operation.
While Peter Torr's answer is correct and is the way Microsoft wants these things to be done, it is possible to make (at least parts of) the OP's code work as well. The reset method will work, if the path is to one of the directories you have permission for. To get these you can use ApplicationData.Current. This object contains properties like LocalFolder, LocalCacheFolder or (what could be interesting for your use case) SharedFolder.

How to store an image from http server to local folder? c# (win8, app)

I want to store an image to a local folder, which i receive from a http-server.
The request (http://myServer:myPort/?imageID=5) delivers a "tif-image-file". If I enter this request into the Internet-Explorer, it works!
My c#-code:
(...)
Uri myUri = new Uri("http://myServer:myPort/?imageID=5");
StorageFile myFile = StorageFile.GetFileFromApplicationUriAsync(myUri);
(...)
But "myFile" is always null :(
What did I do wrong?
Thanks!
Invisibly
OK here is my solution:
I created an empty file in my folder
string myFilename = "myfile.tif";
StorageFile myFile = await myFolder.CreateFileAsync(myFilename, CreationCollisionOption.ReplaceExisting);
BackgroundDownloader
try
{
var download = new BackgroundDownloader().CreateDownload(myUri, myFile);
await download.StartAsync();
}
catch (Exception E)
{
...
}
The next problem is, it works only if I change the Release-Mode from "X64" to "AnyCPU" and vice versa each time. If I dont change the Release-Mode my app does nothing. No Exception, no program crash...
Is this a bug?
(sorry for my bad english...)
The GetFileFromApplicationUriAsync method is itended to be used to load local application ressources. So it's not suited for your case. You need to create a new Storage file using the CreateStreamedFileAsnyc method:
http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.storagefile.createstreamedfileasync.aspx
EDIT: In your case it'll be easier to use CreateStreamedFileFromUriAsync(): http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.storagefile.createstreamedfilefromuriasync.aspx

IsolatedStorageFile's MoveFile() method throws IsolatedStorageException

Description:
The code below is the simplest code I could write which causes the failure. I've also tried: putting the CreateFile and MoveFile in different using statements, putting them in different xaml pages, moving the file into a subdirectory with a new filename, moving it into a subdirectory with the same filename. They all throw the same exception. CopyFile throws the same exception in all circumstances.
Question is--what incredibly simple thing am I not accounting for?
Open a new Silverlight for Windows Phone 7 project targeting Windows Phone 7.1.
Open App.xaml.cs.
Paste the following lines of code into Application_Launching:
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
isf.CreateFile("hello.txt");
isf.MoveFile("hello.txt", "hi.txt");
}
Click start debugging, targeting emulator or device.
Expected: creates a file named "hello.txt", then (effectively) renames "hello.txt" to "hi.txt".
Actual: throws exception below.
System.IO.IsolatedStorage.IsolatedStorageException was unhandled
Message=An error occurred while accessing IsolatedStorage.
StackTrace:
at System.IO.IsolatedStorage.IsolatedStorageFile.MoveFile(String sourceFileName, String destinationFileName)
at PhoneApp4.App.Application_Launching(Object sender, LaunchingEventArgs e)
at Microsoft.Phone.Shell.PhoneApplicationService.FireLaunching()
at Microsoft.Phone.Execution.NativeEmInterop.FireOnLaunching()
You should call Close after you create the file.
IsolatedStorageFileStream helloFile = store.CreateFile("hello.txt");
helloFile.Close();
isf.MoveFile("hello.txt", "hi.txt");
I was just having the same issue, but the solution is simple:
The target file must not exists, delete it before the moving. Make sure the target file is not open anywhere before deleting.
The source file must not be open anywhere.
if (_isolatedStorage.FileExists(targetPath))
{
_isolatedStorage.DeleteFile(targetPath);
}
_isolatedStorage.MoveFile(sourcePath, targetPath);
Perfectly execute this piece of code
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(oldName);
await file.RenameAsync(newName);
MBen, your answer is not correct. Calling Close on the file does not fix this error. I am seeing the exact same error as well even though I call "Close" before MoveFile.
edit Ok just figured out the problem I was having - if you try to call MoveFile when the destinationFile already exists, it throws an Exception. You have to delete the destinationFile first before moving your sourceFile to it.

Categories