How can I get to know whether a directory is writable?

0

I am making a custom SaveFileDialog.

Here is a directory:

C:\Windows\System32\0409

It is readable but unwritable.

I usually use this way to get to know whether it is readable:

    foreach (string i in Directory.GetDirectories(@"C:\Windows\System32\", "*", new EnumerationOptions { IgnoreInaccessible = true }))
    {
    ////
    }

However, this way can't get whether it is writable.

When the program writes a file to an unwritable directory, it will throw the error below:

System.UnauthorizedAccessException
  HResult=0x80070005
  Message=Access to the path 'C:\Windows\System32\0409\' is denied.
  Source=System.IO.FileSystem
  StackTrace:
   at System.IO.FileSystem.CreateDirectory(String fullPath, Byte[] securityDescriptor)
   at System.IO.Directory.CreateDirectory(String path)
   at CoolDuck.Dialogs.Extract.<Window_Loaded>b__26_0() in G:\SampleProject\Test.xaml.cs:line 128
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__277_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)

I don't want to use a try&catch to solve this. I don't think it is the right way.

How can I solve this? Thank you.

c#
asked on Stack Overflow Oct 8, 2020 by Melon NG

2 Answers

6

File IO is always something heavily using try/catch. Cause even if you check the ACL permission and decide you can write, the system could change the ACL right before you start and you ran into the permission exception which you have to handle anyway.

answered on Stack Overflow Oct 8, 2020 by Oliver
-1

This might help you. When File IO is used try/catch blocks are very often used to check these kind of problems.

Example Method:

public bool IsDirectoryAccessable(string dirPath, bool throwIfExc = false)
{
    try
    {
        using (FileStream fileStream = File.Create(
            Path.Combine(
                dirPath, 
                Path.GetRandomFileName()
            ), 
            1,
            FileOptions.DeleteOnClose)
        )
        { }
        return true;
    }
    catch
    {
        if (throwIfExc)
            throw;
        else
            return false;
    }
}
answered on Stack Overflow Oct 8, 2020 by AztecCodes

User contributions licensed under CC BY-SA 3.0