System.UnauthorizedAccessException
The exception that is thrown when the operating system denies access because of an I/O error or a specific type of security error.
Minimum version: >= 1.1 >= Core 1.0
Statistics
How to handle it
try
{
}
catch (System.UnauthorizedAccessException e)
{
}
try
{
}
catch (System.UnauthorizedAccessException e) when (e.Message.Contains("something"))
{
}
try
{
}
catch (System.UnauthorizedAccessException e) when (LogException(e))
{
}
private static bool LogException(Exception e)
{
logger.LogError(...);
return false;
}
How to avoid it
We haven't written anything about avoiding this exception yet. Got a good tip on how to avoid throwing System.UnauthorizedAccessException? Feel free to reach out through the support widget in the lower right corner with your suggestions.
Links
YouTube videos
Possible fixes from StackOverflow
UPDATE:
Modified the code based on this answer to get rid of obsolete methods.
You can use the Security namespace to check this:
public void ExportToFile(string filename)
{
var permissionSet = new PermissionSet(PermissionState.None);
var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, filename);
permissionSet.AddPermission(writePermission);
if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
{
using (FileStream fstream = new FileStream(filename, FileMode.Create))
using (TextWriter writer = new StreamWriter(fstream))
{
// try catch block for write permissions
writer.WriteLine("sometext");
}
}
else
{
//perform some recovery action here
}
}
As far as getting those permission, you are going to have to ask the user to do that for you somehow. If you could programatically do this, then we would all be in trouble ;)
It seems that the problem is that kind of a File.Exists()
check is done internally, which fails if the file is hidden (e.g. tries to do a FileMode.Create
on a file which already exists).
Therefore, use FileMode.OpenOrCreate
to make sure that the file is opened or created even if it is hidden, or just FileMode.Open
if you do not want to create it if it doesn't exist.
When FileMode.OpenOrCreate
is used though, the file will not be truncated, so you should set its length at the end to make sure that there is no leftover after the end of the text.
using (FileStream fs = new FileStream(filename, FileMode.Open)) {
using (TextWriter tw = new StreamWriter(fs)) {
// Write your data here...
tw.WriteLine("foo");
// Flush the writer in order to get a correct stream position for truncating
tw.Flush();
// Set the stream length to the current position in order to truncate leftover text
fs.SetLength(fs.Position);
}
}
If you use .NET 4.5 or later, there is a new overload which prevents the disposal of the StreamWriter
to also dispose the underlying stream. The code could then be written slighly more intuitively like this:
using (FileStream fs = new FileStream(filename, FileMode.Open)) {
using (TextWriter tw = new StreamWriter(fs, Encoding.UTF8, 1024, true)) {
// Write your data here...
tw.WriteLine("foo");
}
// Set the stream length to the current position in order to truncate leftover text
fs.SetLength(fs.Position);
}
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 bothbroadFileSystemAccess
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.
There are two things which can cause the instantiation of a second or subsequent NamedPipeServerStream on the same pipe to fail:
- the maxNumberOfServerInstances ctor argument must have been set to more than 1 when the first instance of the pipe server was created. If not, the second call will fail unless the first instance has already been closed completely.
- the process calling the ctor must have the access right represented by PipeAccessRights.CreateNewInstance. This is a powerful right which the pipe server should guard jealously, as it allows its possessor the ability to act as a pipe server.
The service process should set the pipe security thus:
PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule(myPipeUsersGroup, PipeAccessRights.ReadWrite, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule(myPipeServerIdentity, PipeAccessRights.FullControl, AccessControlType.Allow));
where:
myPipeUsersGroup
is a placeholder for a group which contains all the prospective client identities which will connect to the pipe. Depending on your requirements/use case this might be a specific client identity, a custom group, or a built in group such as "Users" or "Administrators".myPipeServerIdentity
is a placeholder for the service identity. This might be set, for example, toWindowsIdentity.GetCurrent().Owner
. When the pipe server is hosted in a Windows service, then even better (but a good deal harder to implement) would be the Logon SID identity of the service process - this would ensure that only the specific service process could create instances of the pipe.
If you want to ensure that pipe access is restricted to just users logged on locally i.e. to prevent remote access across a network, you can also add a deny ACE for Network Users into the pipe security ACL.
EDIT 2: This answer solve the problem, but is not the correct way to deal with the problem. You should look for Lucero's answer.
Took this answer from: http://www.dotnetspark.com/Forum/314-accessing-hidden-files-and-write-it.aspx
1- Set File as Visible so it can be overwritten
// Get file info
FileInfo myFile= new FileInfo(Environment.CurrentDirectory + @"\hiddenFile.txt");
// Remove the hidden attribute of the file
myFile.Attributes &= ~FileAttributes.Hidden;
2- Make changes to the file
// Do foo...
3- Set back file as hidden
// Put it back as hidden
myFile.Attributes |= FileAttributes.Hidden;
EDIT: I fixed some problem on my answer as mentionned by briler
Source: Stack Overflow