如何在 C# 中的文件上设置清除属性“X”?
Posted
技术标签:
【中文标题】如何在 C# 中的文件上设置清除属性“X”?【英文标题】:How to set clear attribute "X" on files with in C#? 【发布时间】:2012-01-26 21:46:07 【问题描述】:我的 USB 可移动存储设备(FAT 文件系统)上有一个隐藏文件。
我使用的是 Windows 7。如果我转到此文件的“属性”窗口,然后转到“详细信息”选项卡,我将看到该文件的属性为 HX
。当我运行cmd
并使用attrib
时,我被告知该文件具有属性H。没有关于X 的内容。我试过help attrib
,但仍然没有关于属性X。
我知道:
H = 隐藏 S = 系统 A = 存档 R = 只读但是,我不知道 X 代表什么。我还发现了 N and E attributes 的用途。
Wikipedia 没有提到 X 属性是什么。
Google 发现了两个提到属性 X 的主题:
undeletable file in delphi file attribute of x。 "better attrib"这些都没有帮助。
我希望能够在 C# 中读取/写入此标志,但到目前为止,我阅读了 FileAttributes
enumeration 的文档并尝试在文件上设置一些列出的属性(使用 File.GetAttributes
& File.SetAttributes
方法)。
这些实验都没有导致属性 X 出现在属性 -> 详细信息中。所以,我不知道如何处理它,特别是因为我仍然不知道属性 X 是什么意思。
那么,什么是属性 X,如何在 C# 中对所选文件设置/清除它?
【问题讨论】:
似乎所有 cmets 都丢失了 - 有人问我执行chkdsk
后属性 X 是否会消失。不,我已经完成了chkdsk
- 没有发现问题并且属性 X 仍然存在。
我猜是故意无效的文件属性。 FAT32 中有两个未分配的位,0x40 和 0x80。这只是一个猜测。
我怀疑汉斯是对的。获取文件属性,将其转换为int
,并以十六进制输出。然后将设置的位与文件属性常量进行比较:msdn.microsoft.com/en-us/library/windows/desktop/…。这应该告诉你哪个位设置不正确。如果要清除属性,请在该 int 中清除它,将 int 转换回 FileAttributes
,然后调用 File.SetAttributes
。
我听从了 Jim 的建议(感谢您的分步指导),并首先尝试获取和设置虚拟文件的属性。得到0x20
(存档文件),然后我将其设置为0x22
,然后虚拟就被隐藏了。试图获取相关文件的属性 - 得到0x42
(设备+隐藏)。试图将其设置为0x2
(只是隐藏),但我被“拒绝访问”阻止了。然后我尝试将 dummy 的属性设置为0x42
。那里没有问题,但是当我检查 dummy 的 Details 选项卡时,它的唯一属性是 H
。如果我现在得到 dummy 的属性,那就是 0x2
。 “0x40
保留;不要使用”。还有什么办法吗?
参见SetFileAttributes function,备注部分。我知道 不使用 是什么意思,但是这个文件已经被其他程序设置了0x40
属性,我希望能够这样做。或将其关闭。
【参考方案1】:
也许我错了,但是...我认为 X 属性意味着该文件具有extended attributes。遗憾的是,无法使用 C# 修改扩展属性。
【讨论】:
我认为您对扩展属性的看法可能是正确的。我现在知道FILE_ATTRIBUTE_DEVICE 0x40
不能使用SetFileAttribute
设置,但也许还有另一种方法可以使用C# 设置或清除此属性。我读过关于EA DATA. SF
的文章,但似乎我还有更多的阅读要做。知道如何从 C# 访问和编辑EA DATA. SF
文件吗? Implementation of EA on FAT, EA - what and how
我尝试了一些可用的文件删除工具,但没有一个可以帮助删除文件。至于EA DATA. SF
,我不确定这个 EA 文件是否在我的 U 盘上。 如何检查它的存在?据说here EA DATA. SF
文件由于其“正在使用”状态而只能在 Windows 之外删除。真的是这样吗?如果由于EA DATA. SF
而无法删除带有attr X的文件,由于win7我也无法删除...格式化flash后如何制作自己的EA DATA. SF
开车?
我询问如何检查EA DATA. SF
文件存在的原因是因为它没有显示在资源管理器中(我已设置显示隐藏文件和系统文件)。我在cmd
中尝试过if exist "EA DATA. SF" echo It's here!
,但没有得到确认。看起来不是 EA DATA. SF
文件使另一个文件无法触及。我可能错了,希望得到帮助。【参考方案2】:
文件属性X
对应于System.IO.FileAttributes.Device
,它的整数值为64
(0x40),使用.NET 时,您无法直接设置此值。问题是当你调用File.SetAttributes(path, fileAttributes)
时它调用了Mscorlib.dll
中的内部dll导入函数,即静态方法Microsoft.Win32.Win32Native.SetFileAttributes
,这是kernel32.dll
的直接dll导入,定义为:
// Microsoft.Win32.Win32Native
[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetFileAttributes(string name, int attr);
简而言之,即使使用kernel32.dll
,您也无法设置此值。请参阅:SetFileAttributes 和 System.IO.FileAttributes。
但是,您可以编写代码来有效地执行与设置或删除此属性相同的操作。
您最好且可能唯一(合理)的答案是保留具有X
权限的模板文件,当您需要将文件设置为具有X
重命名现有文件时,复制模板X
文件,然后写入其他属性。
要删除X
权限,您应该读取文件并写入新文件,然后使用对File.SetAttributes(path, File.GetAttributes(oldPath));
的简单调用将权限复制到那里(这不会设置X
权限。
这种方法非常简单,并且在本机 .NET 中完全可以实现(与在磁盘级别进行修改或调用 cgywin 相比,实际上看起来也不会太讨厌 - 如果这甚至可以工作的话)。
【讨论】:
【参考方案3】:不幸的是,Windows API 会阻止您设置/取消设置 FILE_ATTRIBUTE_DEVICE,因为它并不打算在文件上设置。如果您确实需要这样做的能力,则必须直接访问磁盘。我真的不建议尝试在 C# 中这样做。
最快的实现可能是忘记在 Windows 中执行此操作,下载 mtools 的源代码并对 mattrib 源代码进行一些编辑以使其正常工作。
例如添加到 msdos.h:
#define ATTR_DEVICE 0x40
#define IS_DEVICE(entry) (HAS_BIT((entry),ATTR_DEVICE))
然后将代码添加到 mattr.c 以便设置属性并验证更改:
static int view_attrib(direntry_t *entry, MainParam_t *mp)
...
/* Add this if block */
if(IS_DEVICE(entry))
putchar('X');
...
static int concise_view_attrib(direntry_t *entry, MainParam_t *mp)
...
/* Add the following if block */
if(IS_DEVICE(entry))
putchar('X');
...
static int letterToCode(int letter)
switch (toupper(letter))
...
/* Add the following case */
case 'X':
return ATTR_DEVICE;
...
然后你只需要在 mtools 上设置你的驱动器并在你想要更改的文件上调用你新创建的 mattrib -x 命令。
【讨论】:
感谢您的回答,但我需要在 Windows 中执行此操作。 啊。当然,如果您仍然卡住,您实际上可以让这段代码在 Cygwin 下运行。【参考方案4】:X 很可能是执行权限。 icalcs
提到了它,您可以使用 C# 中的此命令来设置文件属性,尽管我不确定它是否适用于 FAT 文件系统。
【讨论】:
我认为“执行”属性不适用于像 FAT 这样的 Windows 文件系统。 我读过关于icacls
的信息,尝试在有问题的文件中使用它,但得到“访问被拒绝”。然后我在 USB 记忆棒上的其他文件上对icacls
进行了一些试验,但并没有走得太远:当我输入icacls dummy
时,我得到的只是dummy D:NO_ACCESS_CONTROL
。即使我尝试了/grant
、/deny
和/remove
,我也无法对虚拟的 ACL 进行任何更改。然后我搜索了一下,根据andreas2610 post 发现“acls首先被ntfs文件系统支持”【参考方案5】:
我无法重现您的问题,但作为删除该属性的解决方法,我认为您可以尝试使用robocopy:
robocopy xattributefile copyoffile /copy:DT
/copy:DT
:指定要复制的文件属性。
这不应该复制属性,但我不知道它是否适用于 X 属性)
【讨论】:
以上是关于如何在 C# 中的文件上设置清除属性“X”?的主要内容,如果未能解决你的问题,请参考以下文章
如何重置/清除 x-editable 表中的所有过滤器(select2、select、input)?