为什么我不能删除在ProgramData中创建的目录?

时间:2015-04-08 11:10:23

标签: python windows permissions file-permissions

我试图创建一个目录然后将其删除(出于测试目的,我将忽略,但如果需要可以提供详细信息)。

像这样:

>>> import os
>>> os.makedirs('C:\\ProgramData\\dir\\test')
>>> os.remove('C:\\ProgramData\\dir\\test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
PermissionError: [WinError 5] Access is denied: 'C:\\ProgramData\\dir\\test'

我总是拒绝访问,虽然我是以管理员身份运行解释器。我也没有问题手动删除目录。

2 个答案:

答案 0 :(得分:3)

使用os.rmdir删除文件夹。 os.remove用于删除文件。

答案 1 :(得分:1)

使用os.rmdir删除目录。在Windows上,这是通过调用WinAPI函数RemoveDirectory来实现的。 os.remove是通过调用DeleteFile实现的,ERROR_ACCESS_DENIED仅用于删除文件。如果filename参数是一个目录,则调用失败并将最后一个错误代码设置为NTSTATUS code,Python 3将为此引发PermissionError

在这种情况下,访问被拒绝错误基于RtlNtStatusToDosError STATUS_FILE_IS_A_DIRECTORY,即division of labor (0xC00000BA) == 5。通常,内核的状态代码比相应的WinAPI错误信息更丰富,但并非总是如此,并且始终不会从一个到另一个的简单映射,具体取决于内核之间的NtOpenFile ,系统进程,服务,环境子系统和应用程序。在这种情况下,我认为内核状态代码无疑比通用访问拒绝错误更具信息性。

在较低级别,尝试通过DeleteFile删除目录时出现错误的原因是,它调用了系统服务NtSetInformationFile,并在FILE_NON_DIRECTORY_FILE中设置了OpenOptions标记} {而RemoveDirectory指定FILE_DIRECTORY_FILE。随后,两个函数都会调用file streams来设置FileDispositionInformation以删除文件或目录。


只是成为一个逆向者,让我们在NTFS文件系统上仅使用 file 操作来实现整个序列。

>>> import os, pathlib
>>> base = pathlib.Path(os.environ['ProgramData'])

创建&#39; dir&#39;目录:

>>> dirp = base / 'dir::$INDEX_ALLOCATION'
>>> open(str(dirp), 'w').close()
>>> os.path.isdir(str(dirp))
True

通过手动将流类型指定为$INDEX_ALLOCATION,打开此文件&#39;实际上创建了一个NTFS目录。顺便提一下,您还可以将多个名为$DATA的流添加到目录。请参阅{{3}}主题。

接下来创建&#39;测试&#39;子目录并调用os.remove删除它:

>>> test = base / 'dir' / 'test::$INDEX_ALLOCATION'
>>> open(str(test), 'w').close()
>>> os.path.isdir(str(test))                       
True
>>> os.remove(str(test))
>>> os.path.exists(str(test))
False

你可能会对此感到惊讶。请记住,在这种情况下,文件名显式指定$INDEX_ALLOCATION流。这取代了FILE_NON_DIRECTORY_FILE标志。你得到了你所要求的。但不要依赖于此,因为这些流是NTFS的实现细节,它不是Windows上唯一使用的文件系统。