如何在C#中为文件设置清晰属性“X”?

24

我在我的USB可移动存储设备(FAT文件系统)上有一个隐藏的文件。

我使用的是Windows 7操作系统。如果我打开该文件的属性窗口并切换到“详细信息”选项卡,我会看到该文件的属性为HX。但是,当我运行cmd并使用attrib命令时,我被告知该文件的属性为H,没有任何关于X属性的信息。我尝试了help attrib命令,但仍然没有找到关于X属性的信息。

我知道:

  • H = 隐藏
  • S = 系统
  • A = 存档
  • R = 只读

然而,我不知道X代表什么。我也找到了关于N和E属性的相关信息。

Wikipedia上没有提到X属性。

谷歌搜索结果中有两个主题涉及到X属性:

但是,这些都没有提供有用的信息。

我想要在C#中读取/写入此标志,但到目前为止我已经阅读了FileAttributes枚举的文档并尝试设置文件的一些列出的属性(使用File.GetAttributesFile.SetAttributes方法)。

这些实验都没有导致属性 X 出现在“属性” -> “详细信息”中。因此,我不知道如何处理它,特别是因为我仍然不知道属性 X 的含义。

那么,什么是属性 X,如何在 C# 中对选定的文件进行设置/清除?


2
我猜测这是一个故意设置的无效文件属性。在FAT32中有两个未分配的位,0x40和0x80。这只是我的猜测。 - Hans Passant
2
我怀疑汉斯是正确的。获取文件属性,将其转换为“int”,并以十六进制输出。然后将设置位与文件属性常量进行比较:http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx。这应该告诉您哪个位被错误地设置了。如果您想清除属性,请在该int中清除它,将int转换回“FileAttributes”,并调用“File.SetAttributes”。 - Jim Mischel
1
我遵循了Jim的建议(感谢详细的指示)并首先尝试获取和设置虚拟文件的属性。得到了0x20(存档文件),然后将其设置为0x22,虚拟文件就隐藏了。试图获取所需文件的属性-得到了0x42(设备+隐藏)。尝试将其设置为0x2(只是隐藏),但我被“拒绝访问”阻止了。然后我尝试将虚拟文件的属性设置为0x42。没有问题,但是当我检查虚拟文件的详细信息选项卡时,唯一的属性是H。如果我现在获取虚拟文件的属性,它只是0x2。“0x40 _保留; 不要使用_”。有其他方法吗? - beam022
请参阅SetFileAttributes函数中的_Remarks_部分。我知道“不要使用”的含义,但是这个文件已经被其他程序设置为0x40属性,我想要能够做同样的事情。或者将其关闭。 - beam022
我不确定你是否需要在Windows中这样做。如果不需要,我的回答可能会有所帮助。 - Kevin Stricker
显示剩余3条评论
5个回答

1

也许我错了,但是我认为X属性意味着该文件具有扩展属性。不幸的是,无法使用C#修改扩展属性。


我认为你关于扩展属性的想法可能是正确的。我现在知道FILE_ATTRIBUTE_DEVICE 0x40不能使用SetFileAttribute设置,但也许有另一种方法可以使用C#来设置或清除此属性。我已经阅读了关于EA DATA. SF的文章,但似乎我还需要更多的阅读。你有什么办法可以从C#中访问和编辑EA DATA. SF文件吗?FAT上EA的实现EA - 是什么以及如何使用 - beam022
我尝试了一些可用的文件删除工具,但它们都没有帮助我摆脱这个文件。至于 EA DATA. SF,我不确定这个 EA 文件是否在我的闪存 USB 驱动器上。如何检查它的存在?据说这里 EA DATA. SF _文件只能在 Windows 之外删除,因为它处于“正在使用”状态_。真的是这样吗?如果我无法删除带有属性 X 的文件,因为 EA DATA. SF,而我也无法删除它,因为它在 win7 中...那么在格式化闪存驱动器后,我该如何**制作自己的 EA DATA. SF**? - beam022
我询问如何检查EA DATA. SF文件是否存在的原因是因为它在资源管理器中不显示(我已经设置显示隐藏和系统文件)。我尝试在cmd中使用if exist "EA DATA. SF" echo It's here!,但没有得到确认。看起来并不是EA DATA. SF文件使其他文件无法触及。我可能错了,希望得到帮助。 - beam022

1

文件属性 X 对应于 System.IO.FileAttributes.Device,其整数值为64(0x40)。在.NET中,您无法直接设置此值。问题在于当您调用File.SetAttributes(path, fileAttributes)时,它会调用内部的dll导入函数Mscorlib.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,您也无法设置此值。请参见:SetFileAttributesSystem.IO.FileAttributes
但是,您可以编写代码来有效地执行与设置或删除此属性相同的操作。
您最好并且可能唯一(合理)的答案是保留一个带有X权限的模板文件,当您需要将文件设置为具有X时,重命名现有文件,复制模板X文件,然后编写其他属性。
要删除X权限,您应该读取文件并写入新文件,然后使用简单的调用File.SetAttributes(path, File.GetAttributes(oldPath));将其复制到权限(不会设置X权限)。
这种方法十分直接,完全可以在本地 .NET 中实现(与在硬盘级别上进行操作或调用 cgywin 相比,看起来也不会太丑陋——如果那样做甚至可行的话)。

1

很遗憾,由于 FILE_ATTRIBUTE_DEVICE 不是用于设置文件的选项,Windows API 将阻止您对其进行设置/取消设置。如果您确实需要这样做的能力,则必须直接访问磁盘。我真的不建议在 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上完成这个任务。 - beam022
啊,当然,如果你还卡在这里,你可能真的能够在Cygwin下使这段代码运行。 - Kevin Stricker

0

我无法重现您的问题,但是作为删除该属性的解决方法,我认为您可以尝试使用robocopy

robocopy xattributefile copyoffile /copy:DT

/copy:DT:指定要复制的文件属性。

这不应该复制属性,但我不知道它是否适用于X属性)


0

X 很可能是执行权限。 icalcs 提到了它,您可以可能使用这个命令从 C# 设置文件属性,尽管我不确定它是否适用于 FAT 文件系统。


我认为“execute”属性不适用于Windows文件系统,如FAT。 - CedX
我了解了icacls,尝试在相关文件上使用它,但是得到了“访问被拒绝”的提示。然后我在USB存储器上的其他文件上进行了一些icacls实验,但是没有取得太大进展:当我键入icacls dummy时,我只得到了dummy D:NO_ACCESS_CONTROL。我无法更改dummy的ACL,即使我尝试了/grant/deny/remove。然后我进行了一些搜索,并发现根据andreas2610帖子,“acls首先由ntfs文件系统支持”。 - beam022

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接