我发现我可以写(例如,将文件复制到)只读目录。也就是说,...Attributes = FileAttributes.ReadOnly
的目录。我甚至可以更改其名称。我发现的唯一不能做的就是删除它。这真的是ReadOnly
唯一阻止的吗?
编辑:
以下是代码:(目录为空。)
(new DirectoryInfo(path)).Attributes = FileAttributes.ReadOnly;
Directory.Delete(path);
它抛出Access to the path 'c:\... is denied.
例外。
但是在将ReadOnly
更改为Normal
之后,它可以正常工作。
那么做什么一个ReadOnly
会阻止它,它会阻止什么? (当然是以编程方式。不:通过Windows资源管理器。)
编辑2:
我收到了链接到文档的答案,说明ReadOnly
不尊重目录,并且可能.Net
负责删除失败。所以我会重新解释一个问题:“在使用C#/ .Net 时,Read-Only如何影响目录?”。
答案 0 :(得分:1)
没有。剥离足够的图层,你会发现用于更改目录属性的函数是SetFileAttributes
:
设置文件或目录的属性。
并注意:
FILE_ATTRIBUTE_READONLY 1(0x1) 一个只读的文件。应用程序可以读取文件,但无法写入或删除它。 目录不符合此属性。有关详细信息,请参阅“您无法在Windows Server 2003,Windows XP或Windows Vista中查看或更改文件夹的只读或系统属性。
(我的重点)
答案 1 :(得分:1)
正如Damien_The_Unbeliever所提到的,如果我们看一下FILE_ATTRIBUTE_READONLY的Win32 API,它会提到:
目录不支持此属性。
另请参阅:http://go.microsoft.com/fwlink/p/?linkid=125896
所以看起来确实可以使用win32或Explorer删除这些目录。但是,.NET似乎在删除它们之前检查目录上的标志。例如,您可以在Directory.Delete上使用DotPeek或Reflector来查看。这就是导致“拒绝访问”错误的原因。
编辑:
我更详细地研究了这一点,似乎不是.NET会抛出拒绝访问错误。请考虑以下测试代码:
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();
}
}
}
在我的机器上运行(win 7)我得到以下输出:
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
我们看到我们收到错误代码5,根据http://msdn.microsoft.com/en-gb/library/windows/desktop/ms681382(v=vs.85).aspx,它是一个访问被拒绝的错误。
我只能假设资源管理器在删除目录之前取消设置readonly属性,这当然很容易。命令rmdir
还会删除标记为只读的目录。
正如文档所示,readonly标志应该不在目录上(即使它似乎在Win 7中),我不会依赖这种行为。换句话说,我不会依赖readonly阻止任何事情。
答案 2 :(得分:1)
文件系统中目录条目的只读属性具有有限的用途。大多数用户都希望目录中的所有文件也变为只读。但是,这不是NTFS如何工作,属性只适用于文件系统对象本身而不是继承"就像安全属性一样。
请注意Explorer如何修改属性在其UI中的工作方式,当您打开它然后它执行任何用户期望的操作时,它会使所有文件都是只读的,而不是在目录本身上设置属性。
但是,是的, 工作,它阻止了对目录对象本身的修改。因此,如果您在代码中打开它,那么这会阻止删除目录。就像它对文件一样。