Access to path denied but the file has no restrictions - c#

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.

Related

How to use long path in XmlDocument.Load()?

I have a long-long path
var path = "\\?\C:\long\paht\to\file\myxml.xml"
I trying to read it:
var xmlDoc = new XmlDocument();
xmlDoc.Load(path);
And get exception here:
system.uriformatexception invalid uri the hostname could not be parsed
Everything else work with long path, but XmlDocument.Load() doesn't. What should i do here? Open file in regular stream and use xmlDoc.Load(stream)?
Trying to answer your question i would refer Microsoft article which states 2 prerequisites you must satisfy, in order to enable Long Path on Windows 10 from version 1607 on.
Supposing you already done those additional required settings, there's an option mostly probable that's the currently missing support in the underlying implementation of XmlDocument's Load method.
I've done your same test, in environment targeting .Net 4.6.2+ which doesn't require any additional config in the application config file (which would been required otherwise):
var path = #"\\?\C:\long\paht\to\file\myxml.xml";
var xmlDoc = new System.Xml.XmlDocument();
//xmlDoc.Load(path); => it breaks as you have seen
// avoid exception check for brevity
FileStream fs = File.Open(path, FileMode.Open);
xmlDoc.Load(fs);
This way you should been able to read the file you need and with, good code management, remove the unnecessary intermediate passage currently required.

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.

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

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.

Read XML file fom "My documents" with metro app Windows 8

I'm having an issues with a reading xml file from "my documents" folder. I created a xml file in the folder Data inside "my documents". I have changed already the Capabilities of the app but at the XmlReader reader line, there is an exception triggered "Access to the path 'C:\Users...\Documents\DomusGest\DomusGestFile.xml' is denied."
StorageFolder storageFolder = null;
StorageFile storageFile = null;
storageFolder = await KnownFolders.DocumentsLibrary.GetFolderAsync("Data");
storageFile = await storageFolder.GetFileAsync("DataXML.xml");
string storageFilePath = storageFile.Path;
XmlReader reader = XmlReader.Create(storageFilePath);
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "Apparmtment"))
{
if (reader.HasAttributes)
{
WriteXML.Text = reader.GetAttribute("name");//write on Win8 App
}
}
}
With this same code, I can read the file if the file is located in a folder of the metro app solution.
What am I doing wrong?
Thanks
You need to go to Properties, capabilities and activate Document Library Access capability. Then you need to update the app manifest declaring what type of document you want to te able to read ".xml" in your case; this can be done from the declarations tab.
This can be done, however, bear in mind this is not the best option for neither the user or you, the developer. For the user this is unsafe and will have to accept the capability, thing that may (though I doubt it) draw back some users. On the other hand, the user may modify this XML easier (or another app) and you will have to deal with it.

Categories