I am attempting to create a directory using this method that fires after a button press in app, as well as add a file to it:
DirectoryInfo d = new DirectoryInfo(#"..\\newFolder\\");
FileInfo f = new FileInfo(#"..\\newFolder\\foo.txt");
if (!d.Exists)
{
d.Create();
}
if (!f.Exists)
{
f.Create().Dispose();
}
Here's the error that is producded in my Universal App as a result of doing this:
An exception of type 'System.UnauthorizedAccessException'
occurred in System.IO.FileSystem.dll but was not handled in user code
Additional information: Access to the path
'C:\Users\[username]\Documents\MyApp\bin\x86\Debug\AppX\newFolder' is denied.
Any one familiar with this error or know of any suggestions?
EDIT
In addition to the below, this is a Great resource for working with file systems in the Windows 10 Universal App environment: File access and permissions (Windows Runtime apps) https://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh758325.aspx
The problem is that you are trying to create a file inside your app's install folder, and that is not allowed for Universal Apps. You can only create folders inside your local data folder.
Try this:
using Windows.Storage;
var localRoot = ApplicationData.Current.LocalFolder.Path;
DirectoryInfo d = new DirectoryInfo(localRoot + "\\test");
if (!d.Exists)
d.Create();
Try This
public static async void WriteTrace()
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFolder LogFolder = await localFolder.CreateFolderAsync("LogFiles", CreationCollisionOption.OpenIfExists);
}
Every application runs under (by) a specific user and inherit it's privileges, authorities, limitations and ...
so
The User that your app runs under it, haven't enough privilege and can't create a folder
SO you can:
Use Impersonation (search impersonation c#) and code your app to runs as another User with required privilege (Like Administrator). after that your application always runs as administrator (or specific user) automatically. (If you impersonation your app as Administrator, Be aware of Security issues)
Run your application as Administrator (or a user with enough privilege) manually. (for Administrator right click on your-app.exe and click on "Run as ...")
Change security settings and access limits for your working directories (e.g C:\Users[username]\Documents\MyApp\bin\x86\Debug\AppX\newFolder ) and give write access to your username
Run your application with Administrative privileges and it should be done.
Related
I have an interactive windows service which run on a Local System account and with Interact with desktop checkbox checked(this is mandatory for my project as my service needs to invoke .exe with UI ). I am getting an exception as Access denied while writing to network drive. I am passing the UNC path from config file. i tried giving full control access to anonymous user on the folder which i want to access but its still not working. i cannot run my windows service under Network service account or under any other account as suggested in some other posts because i want it interact with desktop check box checked. is there any way to achieve this?
Edit: UNC path of network drive: //server/ABC/pqr
my service should create .txt file in pqr folder. should have access to delete it afterwords too.
i have tried creating anonymous user for pqr folder and giving it full control but still i am getting access denied exception. as i mentioned before i cannot run it under any other account other than local system account because it will automatically disable interact with desktop option in the properties of that service. is there any way to make it run under Network Service Account and still keep it interactive(interact with desktop option checked in the properties of service)?
Try using the following nugget package named SimpleImpersonation
This way you could wrap the code you use to access your remote file location like this:
using (Impersonation.LogonUser(domain, username, password, logonType))
{
// do whatever you want as this user.
}
It worked for me. I used it to turn on and turn off a windows service remotely. Like this:
await Task.Factory.StartNew(() =>
{
using (
Impersonation.LogonUser(serviceInfo.Domain, serviceInfo.User, serviceInfo.Pswd,
Environment.MachineName.Equals(serviceInfo.ComputerName,
StringComparison.InvariantCultureIgnoreCase)
? LogonType.Network
: LogonType.Interactive))
{
var service = new ServiceController(serviceInfo.ServiceName, serviceInfo.ComputerName);
if (service.Status == ServiceControllerStatus.Stopped)
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(60));
}
else
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(60));
}
}
});
(the snippet was taken from the project site)
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
I have had some problems earlier which caused my program to crash in all Windows OS because I did not create a new file/directory for my file. Then I have assured that I have created file/folder before initializing ect. Now my program works in Windows XP but it doesn't work in Windows 7. By saying that it works I mean that it creates a file/folder needed for my program. By not working I mean that the file/folder isn't created in windows 7.
Could this code be the cause of the crash under Windows 7? If so, how could I fix it?
private static string dir = Environment.GetFolderPath
(Environment.SpecialFolder.ProgramFiles) + #"\folder\";
private static string file = dir + #"\Settings.txt";
private string text;
public void CheckFileStatus()
{
if (!Directory.Exists(dir))
{
DirectoryInfo directory = Directory.CreateDirectory(dir);
}
if (!File.Exists(file))
{
using (FileStream fileStream = File.Create(file))
{
}
}
}
The program files directory in Windows 7 can only be written to with elevated privileges. Are you running your code as an administrator? It's also bad practice to write to the program files folder. You should be using the %appdata% folder.
Take a look here to see the various special folders. You will likely want to use either System.Environment.SpecialFolder.ApplicationData or System.Environment.SpecialFolder.CommonApplicationData. This will allow you to write data without needing elevated privileges.
You cannot create folders in Program Files without being having elevated privileges (ie acting as an Administrator) on Windows Vista and Windows 7. There are generally better places to put settings files that should be writable by any user.
Environment.SpecialFolder.ApplicationData or Environment.SpecialFolder.LocalApplicationData is generally the place for user specific application data which is most likely what you want.
The difference being that in a domain, ApplicationData will be placed in your roaming profile and be shared between computers on the domain, while LocalApplicationData is for that very machine only.
For home users or if you don't specifically want the data to be shared between machines, probably LocalApplicationData is better. That way you know it won't cause problems on a domain if you end up writing computer specific data in it.
There is also Environment.SpecialFolder.CommonApplicationData which allows for sharing the same data between all users on the computer, but while that may seem convenient, consider that any user on the machine can then change settings of a program that is later run by you which may cause security implications.
I am developing an application using c# and asp. It need to access some places in the local network . There is a text box in the form which accept the path to be accessed from the user and will store it to a string variable named location.
The if loop always return false if the application run in windows 7. and it occurs only when I run from the installed application, otherwise it will return true if the path is true. Here is the code:
The input to textbox BackupLocation is like this
\\192.168.0.33\Others (F)
. It work fine if the application is hosted on a system which have windows XP
System.IO.DirectoryInfo locationInfo = new System.IO.DirectoryInfo(BackupLocationTxt.Text);
if (locationInfo.Exists) // always return false if the application run in windows 7
{
}
Why this happens ?
This happens because the user you are running your application under doesn't have authorization to read those folders. You might need to grant read access to those folders to the account you are running your site under.
Try System.IO.Directory.Exists(string path) instead.
Your ASP.NET application doesn't have permissions to the folder on other computer in local network.
Try use windows service started under LocalService account.
I know that user accounts in Windows 7 are limited by default, so a program cannot just write anywhere on the system (as it was possible in Win XP).
But I thought that it would be possible that e.g. a c# app is allowed to write inside it's own exe-directory or it's subfolders at least (not everything is 'user settings' or should be written to "MyDocuments"...).
So currently my c# app throws an UnauthorizedAccessException when trying to write inside the exe dir.
Is there anything you can do in c# code to allow writing inside the exe dir?
No, if the user your application is running under doesn't have permissions to write to this folder you cannot write to it. When installing your application (probably through an MSI) you could grant the necessary rights.
You could also provide a manifest file with your application.
Is there anything you can do in c# code to allow writing inside the exe dir?
Yes, but this code (that changes the permissions) would need to be executed with admin permission, so you're back at the start.
In my opinion, the correct way would be to set up appropriate write permissions to a directory below C:\ProgramData (actually: Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)) in a custom action during the installation of your software.
Yes.
Install the program in a location where user's have write/modify rights.
(Of course this opens you to those same users modifying your program.)
Yes, you should make sure you're program runs with admin privileges.
You can do this manually by rightclicking on the exec and click "Run as Administrator" or you can demand from code that the program runs with admin privileges.
WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);
if (!hasAdministrativeRight)
{
RunElevated(Application.ExecutablePath);
Environment.Exit(0);
}
private static void RunElevated(string fileName)
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Verb = "runas";
processInfo.FileName = fileName;
try
{
Process.Start(processInfo);
}
catch (Win32Exception)
{
MessageBox.Show("Program needs administrator rights");
}
}