UWP: Access to the path denied [duplicate] - c#

I´m developing an app that is reading jpeg and pdf files from a configurable location on the filesystem.
Currently there is a running version implemented in WPF and now I´m trying to move to the new Windows Universal apps.
The following code works fine with WPF:
public IList<string> GetFilesByNumber(string path, string number)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentNullException(nameof(path));
if (string.IsNullOrWhiteSpace(number))
throw new ArgumentNullException(nameof(number));
if (!Directory.Exists(path))
throw new DirectoryNotFoundException(path);
var files = Directory.GetFiles(path, "*" + number + "*",
SearchOption.AllDirectories);
if (files == null || files.Length == 0)
return null;
return files;
}
With using Universal Apps I ran into some problems:
Directory.Exists is not available
How can I read from directories outside of my app storage?
To read from an other directory outside the app storage I tried the following:
StorageFolder folder = StorageFolder.GetFolderFromPathAsync("D:\\texts\\");
var fileTypeFilter = new string[] { ".pdf", ".jpg" };
QueryOptions queryOptions = new QueryOptions(CommonFileQuery.OrderBySearchRank, fileTypeFilter);
queryOptions.UserSearchFilter = "142";
StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList<StorageFile> files = queryResult.GetFilesAsync().GetResults();
The thing is: It isn´t working, but I get an exception:
An exception of type 'System.UnauthorizedAccessException' occurred in TextManager.Universal.DataAccess.dll but was not handled in user code
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
I know that you have to configure some permissions in the manifest, but I can´t find one suitable for filesystem IO operations...
Did someone also have such problems/a possible solution?
Solution:
From the solutions that #Rico Suter gave me, I chosed the FutureAccessList in combination with the FolderPicker. It is also possible to access the entry with the Token after the program was restarted.
I can also recommend you the UX Guidlines and this Github sample.
Thank you very much!

In UWP apps, you can only access the following files and folders:
Directories which are declared in the manifest file (e.g. Documents, Pictures, Videos folder)
Directories and files which the user manually selected with the FileOpenPicker or FolderPicker
Files from the FutureAccessList or MostRecentlyUsedList
Files which are opened with a file extension association or via sharing
If you need access to all files in D:\, the user must manually pick the D:\ drive using the FolderPicker, then you have access to everything in this drive...
UPDATE:
Windows 10 build 17134 (2018 April Update, version 1803) added additional file system access capabilities for UWP apps:
Any UWP app (either a regular windowed app or a console app) that declares an AppExecutionAlias is now granted implicit access to the files and folders in the current working directory and downward, when it’s activated from a command line. The current working directory is from whatever file-system location the user chooses to execute your AppExecutionAlias.
The new broadFileSystemAccess capability grants apps the same access to the file system as the user who is currently running the app without file-picker style prompts. This access can be set in the manifest in the following manner:
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
...
IgnorableNamespaces="uap mp uap5 rescap">
...
<Capabilities>
<rescap:Capability Name="broadFileSystemAccess" />
</Capabilities>
These changes and their intention are discussed at length in the MSDN Magazine article titled Universal Windows Platform - Closing UWP-Win32 Gaps. The articles notes the following:
If you declare any restricted capability, this triggers additional
scrutiny at the time you submit your package to the Store for
publication. ... You don’t need an AppExecutionAlias if you have this
capability. Because this is such a powerful feature, Microsoft will
grant the capability only if the app developer provides compelling
reasons for the request, a description of how this will be used, and
an explanation of how this benefits the user.
further:
If you declare the broadFileSystemAccess capability, you don’t need to
declare any of the more narrowly scoped file-system capabilities
(Documents, Pictures or Videos); indeed, an app must not declare both
broadFileSystemAccess and any of the other three file-system
capabilities.
finally:
Even after the app has been granted the capability, there’s also a
runtime check, because this constitutes a privacy concern for the
user. Just like other privacy issues, the app will trigger a
user-consent prompt on first use. If the user chooses to deny
permission, the app must be resilient to this.

The accepted answer is no longer complete. It is now possible to declare broadFileSystemAccess in the app manifest to arbitrarily read the file system.
The File Access Permissions page has details.
Note that the user can still revoke this permission via the settings app.

You can do it from UI in VS 2017.
Click on manifest file -> Capabilities -> Check photo library or whatever stuff you want.

According to MSDN doc : "The file picker allows an app to access files and folders, to attach files and folders, to open a file, and to save a file."
https://msdn.microsoft.com/en-us/library/windows/apps/hh465182.aspx
You can read a file using the filepicker through a standard user interface.
Regards

this is not true:
Files which are opened with a file extension association or via sharing
try it, by opening files from mail (outlook) or from the desktop...
it simply does not work
you first have to grant the rights by the file picker.
so this ist sh...

This is a restricted capability. Access is configurable in Settings > Privacy > File system. and enable acces for your app. Because users can grant or deny the permission any time in Settings, you should ensure that your app is resilient to those changes. If you find that your app does not have access, you may choose to prompt the user to change the setting by providing a link to the Windows 10 file system access and privacy article. Note that the user must close the app, toggle the setting, and restart the app. If they toggle the setting while the app is running, the platform will suspend your app so that you can save the state, then forcibly terminate the app in order to apply the new setting. In the April 2018 update, the default for the permission is On. In the October 2018 update, the default is Off.
More info

Related

How to Read myFolder txt File in UWP

I want to Read textFile in my Userfolder in UWP but i got error like this
'Access to the path 'C:\Users\Administrator\log\config.txt' is denied.'
string path = #"C:\Users\Administrator\log\config.txt";
string textValue = System.IO.File.ReadAllText(path);
Debug.WriteLine(textValue);
UWP can't read folder in a specific path???
UWP was designed as a sandbox to increase a user security. Thus, by default your app can see only limited list of folders, like its private subfolder or any of standard locations like My Docs, My Pictures etc. If you need something outside the default, there is a manifest permission to be specified (broadFileSystemAccess) or then let the user pick deisred file interactively to get explicit consent:
https://learn.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations
In most cases, to get access to file system locations, your app can
use the FileOpenPicker, FileSavePicker, FolderPicker, and
FutureAccessList APIs. If you want to request approval to use the
broadFileSystemAccess capability, then you must provide specific
reasons as to why those APIs aren't sufficient for your needs.

UWP FolderPicker does not grant me permission to access folder

The following code is taken from Microsoft's documentation on the subject with slight modification:
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
folderPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
folderPicker.FileTypeFilter.Add("*");
Windows.Storage.StorageFolder folder = await folderPicker.PickSingleFolderAsync();
if (folder != null)
{
// Application now has read/write access to all contents in the picked folder
// (including other sub-folder contents)
Windows.Storage.AccessCache.StorageApplicationPermissions.
FutureAccessList.AddOrReplace("PickedFolderToken", folder);
if (Directory.Exists(folder.Path)) // fails, I don't have permission to read this folder even though the documentation suggests that I should have access
{
this.textBlock.Text = "Picked folder: " + folder.Name; // never gets printed
}
}
I also tried adding the broadFileSystemAccess capability to the application manifest. What am I missing here?
broadFileSystemAccess only works with Windows.Storage namespace, and this is already mentioned in the docs as follows :
This is a restricted capability. On first use, the system will prompt
the user to allow access. Access is configurable in Settings > Privacy
File system. If you submit an app to the Store that declares this capability, you will need to supply additional descriptions of why
your app needs this capability, and how it intends to use it. This
capability works for APIs in the Windows.Storage namespace
UWP applications have limited access and the regular IO commands do not work, including System.Diagnostic.Process. The only way to launch a process is to use FullTrustProcessLauncher Class as documented here: https://learn.microsoft.com/en-us/uwp/api/Windows.ApplicationModel.FullTrustProcessLauncher.
Working examples can be found here: https://github.com/StefanWickDev/UWP-FullTrust
However, this does not solve the problem of working with existing libraries since they are not processes in the first place. We now have an RPC service where the requests are made from the service and results obtained.

ERROR: System.Environment.SpecialFolder' does not contain a definition for 'CommonApplicationData'

I have the code to save a file in a folder in directory
string timestamp = DateTime.Now.ToString("MM-dd-yyyy.HH-mm-ss");
var file = File.Create("Owe-Data.txt" + timestamp);
var com = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase + timestamp + #"\Data" + file;
MessageBox.Show(com);
if (!Directory.Exists(com))
{
Directory.CreateDirectory(com);
}
using (var sw = new StreamWriter(com))
{
sw.WriteLine(InputData);
}
}
i Displayed COM it gives path bt i cant see the Data folder or Owe-Data file at that path
Anybody can tell why this happening, or should i save the Data folder in current directory where this prgram running? bt i dnt know how to reach that path. Any solutions ??
Working on windows phone 5, visual studio 2008 .NET framwork 2.0
As per the Exceptions section of documentation,the above exception is thrown when
ArgumentException ------- folder is not a member of System.Environment.SpecialFolder.
It means the OS where you are running this command does not have Environment.SpecialFolder.CommonApplicationData as one of the special folder.
For knowledge,
Environment.SpecialFolder.ApplicationData is the most common one. This folder holds per-user, non-temporary application-specific data, other than user documents. A common example would be a settings or configuration file.
Environment.SpecialFolder.CommonApplicationData is similar, but shared across users. You could use this to store document templates, for instance.
Environment.SpecialFolder.LocalApplicationData is a non-roaming alternative for ApplicationData. As such, you'd never store important data there. However, because it's non-roaming it is a good location for temporary files, caches, etcetera. It's typically on a local disk.
I think the problem may be that Environment.SpecialFolder.CommonApplicationData is common and shared between different users and the user with which you have logged in is not having rights to access the folder or the Visual Studio has not been started in Admin mode.
EDIT Look at link and try to add a manual registry Common AppData defined in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\
Given you are asking about a .NET Windows Phone application as per the tags
I think your problem is that a .NET Windows Phone application does not have direct access to the file system; it can only access IsolatedStorage this is by design.
I would quote a Microsoft source for this but I can't seem to find one!
EDIT
See this article from MSDN

WPF app writes files/data into "C:\ProgramData" but fails to write into other folders

We have developed WPF application which allows user to select folder path. WPF application writes files/data into this selected path. When we select "C:\ProgramData" as the path, it creates the file and write the data. But when the path is other than "C:\ProgramData", file is generated but data is not written into the file and it seems a permission issue. Can anybody help us in finding out , how we can assign the same kind of permission to selected folder same as "C:\ProgramData" so that it allows to write data into the file. In conclustion what is the extra permission does "ProgramData" has which is not their for other folders?
Note: it only works properly with ProgramData folder.
Whenever your application is launched with standard user rights, it can write to only those folders to which a standard user can write to. E.g. are:
C:\Users\USERNAME\
C:\ProgramData\
D:\
It will not be able to write to folders like:
C:\
C:\Users\SOME_OTHER_USERNAME\
c:\Windows
C:\Windows\System32 etc
For that you either need to disable UAC or launch the application with administrative permissions.
I would suggest that whenever user selects a folder from your application check if you can create a file/ folder in that location before accepting the path.
solution what i can give is let's user select the path after you get the folder path just check whether you can write data to it , see this code
bool HasAccessToWrite(string path)
{
try
{
using (FileStream fs = File.Create(Path.Combine(path, "Access.txt"), 1, FileOptions.DeleteOnClose))
{
}
return true;
}
catch
{
return false;
}
}
#Ganesh is right but you may go with one of the following options:
Run the installer with admin rights, ask user to select target folder during installation and set the permissions to everyone or required groups of users/roles.
If above is not applicable then configure your application to always run under admin account, in that way it will have access to all folder to write data. To configure run as admin user application manifest as explained here:
Turn off UAC, not a recommended approach though.
I had same issue so, I forced installer to be run under admin rights and asked user to create target folders during installation. Used a custom action to set full rights for everyone user group on the target folder. Since security was not issue for us so, it was ok to allow everyone but consider your environment before using this option.

C# Application can't read/write to files created by administrator when run in limited user account XP

I have an application that is useable by all users (admin or limited) in .NET (C# specifically).
When the application first launches - it creates a few files that it needs in the C:\Documents and Settings\All Users\Documents\ for all subsequent launches.
If the limited user in XP is the FIRST user to launch the application it creates the files fine and both the limited user and administrators can run fine.
However if the Administrator (or I am guessing a different limited user) is the first to launch the application then the limited user is NOT able to run the application.
The two files that it is NOT able to read/write to if created by an Administrator is a Log4Net log file and a SQLite db file.
The SQLite database file is being created with a straitforward .NET File.Copy(sourcepath, destinationpath). The sourcepath is a seed database file installed with the application - so on first run it copies that from the C:\Program Files\app install\seed.db
Is there a way to set the permissions on the file when I copy it? File.SetAccessControl() perhaps? I am not clear on how that works.
The other issue is that the log4Net rolling file appender will not roll the old file and create a new as the old file was created by the admin user when they ran the app.
Any ideas? Ironically this all works perfectly fine in Vista with limited/admin accounts - this is ONLY happening in XP with admin/limited accounts.
I think SetAccessControl is the way to go. Maybe something like this:
// get the existing access controls
FileSecurity fs = File.GetAccessControl(yourFilename);
// add the new rule to the existing settings
fs.AddAccessRule(new FileSystemAccessRule(
#"DOMAIN\Users", // or "BUILTIN\Users", "COMPUTER\AccountName" etc
FileSystemRights.Modify,
AccessControlType.Allow));
// set the updated access controls
File.SetAccessControl(yourFilename, fs);
Note: It's important that you get the existing access control list from the file and then add your new rule to that. If you just create a new access control list from scratch then it will overwrite the existing permissions completely.
Yeah, it's the SetAccessControl method all right, there is a good example here
(the post from satankidneypie)
Good luck

Categories