I'm running into an issue where I can read from a file in the app install directory but can't write to it.
In the below code, I open a file for reading, do stuff, dispose of my stream pointers, then try to open the file for writing.
//Open file for reading
var SocStorageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///LastSoc.txt"));
var SocInputStream = await SocStorageFile.OpenReadAsync();
var SocClassicStream = SocInputStream.AsStreamForRead();
var SocStream = new StreamReader(SocClassicStream);
<do stuff with file read>
.....
SocInputStream.Dispose();
SocClassicStream.Dispose();
SocStream.Dispose();
//Open record file for writing
var RandomAccessStream = await
SocStorageFile.OpenAsync(FileAccessMode.ReadWrite);
When I try the last line to enable write access, I get:
System.UnauthorizedAccessException: 'Access is denied. (Exception from
HRESULT: 0x80070005 (E_ACCESSDENIED))'
Worried that my Dispose() methods didn't completely clean it up, I tried commenting out all my read accesses. Same error. (Yeah I know, i should use 'using' but I don't think that's the problem here)
I'm not sure why I can't obtain write access. Advice appreciated thanks!
From the path specified in your code, it looks like you are attempting to write to a file that is part of your app's package. This file exists in the installation folder of your app which you only have read only access to.
Simply put, you can read application files in the installation directory but you can't write to files in that directory. This is also true for creating new files in the app installation directory.
Have a look at this doc from Microsoft explaining file access in UWP: https://learn.microsoft.com/en-us/windows/uwp/files/file-access-permissions
From the doc linked above, the important part is:
The app's install directory is a read-only location. You can't gain access to the install directory through the file picker.
Now, if you are planning on updating this file's content, you should move it to the Application Data folder ( ApplicationData.Current.LocalFolder ). UWP apps are allowed to read and write (and create new files) in that directory.
Related
I'm trying to save a file without a filepicker under my desktop or somewhere else, but I always get the error "Access to path [...] is denied"
This is my code:
private async void SaveFile(string Path)
{
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(Path);
StorageFile sampleFile = await folder.CreateFileAsync("sample.txt", Windows.Storage.CreationCollisionOption.ReplaceExisting);
}
I tried the same code but with the Localfoder and it worked.
Is there any way to get access to the path without a filepicker?
Using FilePicker gets permission from the user to access file locations. File system access is a restricted capability in UWP. You can enable Broad Filesystem Access in your package manifest to get this permission when the app is installed. It's not recommended for apps published to the Microsoft Store, because it makes it less likely for you app to be approved. See the App capability declarations documentation.
Alternatively, you could run your app from a folder that contains the desktop in one of its subfolders by using the AppExecutionAlias extension mention under Accessing additional locations in File Access Permissions. Underneath that section there is also an explanation of Broad Filesystem Access as well.
I am trying to edit a existing Word document using the UWP app (Universal Windows). But for some reason I am getting "File does not exist" error.
I have tried using the below code to access the word document:
using(WordprocessingDocument wordDoc = WordprocessingDocument.Open("C:\\Users\\Public\\Desktop\\Doc1.docx", true))
{
}
System.IO.FileNotFoundException: 'Could not find document'
Based on further clarification in the comments section, please see the following instructions.
Add your .DOCX file to the Assets folder within your project and set the build action to "Content".
In order to write any changes to the file, we'll need to copy it to the packages LocalFolder and then access it from there.
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/doc1.docx"));
if (file != null)
{
//Copy .docx file to LocalFolder so we can write to it
await file.CopyAsync(ApplicationData.Current.LocalFolder);
String newFile = ApplicationData.Current.LocalFolder.Path + "/doc1.docx";
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(newFile, true))
{
//Your code here
}
}
You'll need to expand on this somewhat to make sure the file is only copied to the LocalFolder once etc, but you get the basic idea.
By default, the UWP doesn't allow to access the files outside the app container. But from windows 10 build 17134, a new capability broadFileSystemAccess has been introduced. It allows apps to get the same access to the file system as the user who is currently running the app without any additional file-picker style prompts during runtime.
So, please check if you have declare this capability in the 'Package.appxmanifest' file.
Please see File access permissions and broadFileSystemAccess entry in App capability declarations for more information.
If you still face this issue when you add the broadFileSystemAccess capability, then, the issue should be in 'WordprocessingDocument.Open' API. You need to note that 'File access permissions' document has mentioned:
This broadFileSystemAccess capability works for APIs in the Windows.Storage namespace.
This means that the 'WordprocessingDocument.Open' may not use the Windows.Storage APIs to access the files. If so, you need to report this issue to Open-XML-SDK.
I started with UWP platform apps and I want create new folder in Temp folder:
StorageFolder temporaryFolder = ApplicationData.Current.TemporaryFolder;
temporaryFolder = await temporaryFolder.CreateFolderAsync
(Path.GetFileNameWithoutExtension(Path.Combine(temporaryFolder.Path, fileName)),
CreationCollisionOption.ReplaceExisting);
Everything looks OK, but when I want to decompress a ZIP file, which is in Temporary folder into folder which one I created then I give exception:
System.UnauthorizedAccessException: Access to the path 'C:\Users\Admin\AppData\Local\Packages\cebff192-8162-4800-9f9c-b3ce1ca8849f_5gyrq6psz227t\TempState\1' is denied.
My question is simple: How I can create a new folder in Temp to which I can write?
You should be able to access the file in the temporary Folder, but it depends on how you access it. When you access the file, please avoid using the file path. See this blog: https://blogs.msdn.microsoft.com/wsdevsol/2012/12/04/skip-the-path-stick-to-the-storagefile/
To open and read a file in the temporary app data store, use the file APIs, such as Windows.Storage.StorageFolder.GetFileAsync. You can get more details about the temporary folder from Temporary app data.
I'm writing a Windows 8.1 store application and am trying to create a subfolder in the ApplicationData.Current.RoamingFolder directory. There is no data currently stored there. However, the following line throws a System.UnauthorizedAccessException saying "Access is Denied".
var folder = await ApplicationData.Current.RoamingFolder.CreateFolderAsync("subfolder", CreationCollisionOption.OpenIfExists);
Strangely enough, if I use LocalFolder instead of RoamingFolder, the operation succeeds.
var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("subfolder", CreationCollisionOption.OpenIfExists);
Why can't I create a subfolder in the roaming folder? I can manually create the folder via Windows Explorer.
The documentation (link) says that there are limitations on what can be placed in the folder, specifically:
"The sync engine has restrictions on the file name conventions that you must follow to ensure the items in the roaming folder can roam. Be sure that your file and folder names do not contain leading whitespace. The sync engine may limit the total size of settings and files that can roam."
However, I don't see anything that would explain the above exception. What am I missing and what other limitations am I missing about the roaming folder?
Interestingly, if I create a brand-new application both lines of code function perfectly. I don't know why that is.
Edit: As mentioned by Nate, the CreateFolderAsync documentation says "If you try to create a subfolder in a virtual folder like a library or a file group, this method may fail." Does anyone know if that applies here? If it does, what limitations does it introduce? The only information I've found on this issue is this question, but it doesn't seem to firmly resolve the issue.
I'm trying to write a blank text file which is included within my installer but i'm getting the following error;
System.UnauthorizedAccessException: Access to the path 'C:\Program Files (x86)\Hex Technologies\wamplocation.txt' is denied.
It seems to be the permissions of the file once it's installed through my installer, but how can I set the file to be fully modifiable once the file installed?! Can this be done through C#?!
EDITTED;
wamp_url = openFileDialog1.FileName.ToString();
String EnviromentPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
StreamWriter outfile = new StreamWriter(EnviromentPath + #"\Hex Technologies\wamplocation.txt");
outfile.Write(wamp_url);
outfile.Close();
You should not store your modifyable data files in the Program Files path. Use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) or Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
The Program Files\... path is protected against modification by normal users on Win7+. It would be a bad idea to try to circumvent that protection.
The likleyhood is the UAC is getting in your way.
Ideally your program shouldn't be writing to this location, it this modification file is to be modified during an install process and nowhere else you need to make sure that you are running elevated.
If this file is to be modified at run time you should consider the use of either %appdata% for user data or %programdata% for program data instead of program files.