How does Read-Only affect a Directory when using C#/.Net?

前端 未结 3 589
南笙
南笙 2021-01-14 08:16

I\'ve found that I can write (say, copy a file into) a Read-Only directory. That is, a Directory with ...Attributes = FileAttributes.ReadOnly.I can even change

3条回答
  •  被撕碎了的回忆
    2021-01-14 08:24

    As Damien_The_Unbeliever mentions, if we look at the Win32 API for FILE_ATTRIBUTE_READONLY it mentions:

    This attribute is not honored on directories.

    See also: http://go.microsoft.com/fwlink/p/?linkid=125896

    So it seems indeed that you can simply delete such directories using win32 or Explorer. .NET, however, seems to check flags on directories before deleting them. You can see this by using DotPeek or Reflector, on Directory.Delete for example. This is what's causing your "access denied" error.

    EDIT:

    I looked into this in a bit more detail, and it seems like it is not .NET which is throwing the access denied error. Consider the following test code:

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    
    namespace ReadOnlyDirTest
    {
       class Program
       {
          [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
          extern static bool RemoveDirectory(string path);
    
          static String CreateTempDir()
          {
             String tempDir;
             do
             {
                tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
             } while (Directory.Exists(tempDir));
    
             Directory.CreateDirectory(tempDir);
             return tempDir;
          }
    
          static void Main(string[] args)
          {
             var tempDir = CreateTempDir();
    
             // Set readonly.
             new DirectoryInfo(tempDir).Attributes |= FileAttributes.ReadOnly;
    
             try
             {
                Directory.Delete(tempDir);
             }
             catch (Exception e)
             {
                Console.WriteLine("Directory.Delete: " + e.Message);
             }
    
             if (!Directory.Exists(tempDir))
                Console.WriteLine("Directory.Delete deleted directory");
    
             try
             {
                if (!RemoveDirectory(tempDir))
                   Console.WriteLine("RemoveDirectory Win32 error: " + Marshal.GetLastWin32Error().ToString());
             }
             catch (Exception e)
             {
                Console.WriteLine("RemoveDirectory: " + e.Message);
             }
    
             if (!Directory.Exists(tempDir))
                Console.WriteLine("RemoveDirectory deleted directory");
    
             // Try again without readonly, for both.
             tempDir = CreateTempDir();
             Directory.Delete(tempDir);
             Console.WriteLine("Directory.Delete: removed normal directory");
    
             tempDir = CreateTempDir();
             if (!RemoveDirectory(tempDir))
                Console.WriteLine("RemoveDirectory: could not remove directory, error is " + Marshal.GetLastWin32Error().ToString());
             else
                Console.WriteLine("RemoveDirectory: removed normal directory");
    
             Console.ReadLine();
          }
       }
    }
    

    Running this on my machine (win 7) I get the following output:

        Directory.Delete: Access to the path 'C:\...\Local\Temp\a4udkkax.jcy' is denied.
        RemoveDirectory Win32 error: 5
        Directory.Delete: removed normal directory
        RemoveDirectory: removed normal directory
    

    We see we get error code 5, which, according to http://msdn.microsoft.com/en-gb/library/windows/desktop/ms681382(v=vs.85).aspx, is an Access Denied error.

    I can then only assume that Explorer unsets the readonly attribute before deleting a directory, which is of course easily done. The command rmdir also removes a directory marked as readonly.

    As the documentation suggests the readonly flag should is not honoured on directories (even though it seems to be in Win 7), I would not rely on this behaviour. In other words I would not rely on readonly preventing anything.

提交回复
热议问题