【问题标题】:When is a file not a file system object?什么时候文件不是文件系统对象?
【发布时间】:2012-01-08 11:26:54
【问题描述】:

我的代码通过 shell API 枚举收藏夹文件夹(递归)。我使用GetAttributesOf函数来获取我找到的每个对象的属性。

因为我从不向上推进,所以我的期望是我遇到的所有项目都是文件系统对象。这可能不适用于所有子目录,但我非常有信心这对有问题的子目录是正确的。

尽管我有信心,但我确认属性包括SFGAO_FILESYSTEM。如果他们不这样做,那么我会记录一条消息并跳过该项目,因为没有希望能够完成我的工作。我希望我永远不会看到日志记录或必须跳过一个项目,但我还是进行了验证,因为这就是我滚动的方式。

几周后,我优秀的 QA 工程师告诉我,他发现我的程序在某个特定项目上出现了异常行为,大约在发生这种情况的时候,他在日志中看到该项目没有设置文件系统位,并且必须跳过。有问题的项目是,我们有充分的理由相信,一个文件。

自从我最初写这个问题以来,我们已经看到枚举中的几个项目声称不是文件系统项目的情况。麻烦似乎持续了很短的时间,但足够长的时间来搞砸多达六个项目的旗帜。

什么时候文件不是文件系统对象?

【问题讨论】:

  • 您是否在枚举可能有子文件夹可能有其他视图的文件夹,例如 Internet 临时文件或 GAC?
  • 我没有列举这些文件夹中的任何一个。我将把问题编辑得更具体。
  • GetAttributeOf() 的调用本身是否失败,使您的标志变量与您初始化的变量保持不变?
  • 好问题,但在那种情况下,我会在有机会测试SFGAO_FILESYSTEM 之前抛出异常。
  • 您是在使用 GetAttributesOf 来查询多个项目,还是只查询一个(如果是后者,为什么不使用 IShellItem::GetAttributes?)。 GetAttributesOf 返回所提供的 shell 项共有的属性,因此单个非文件对象将抑制 SFGAO_FILESYSTEM 标志。最后,您是否记录了更多信息,例如非文件对象的名称?

标签: file winapi windows-shell filesystemobject


【解决方案1】:

目前尚不清楚您使用的是旧文件系统还是 NTFS,但有几件事可能会破坏文件系统位 - Vista 引入了符号链接,这与常规快捷方式不同,因为它们解析“客户端-side”它们本身可能不算作文件系统对象。目录重解析点也是如此。 SFGAO 枚举并不完全是 NTFS 中发生的事情的 1:1 表示,因此请谨慎对待它的信息。

坏块也有可能导致 Windows 报告文件系统位不一致。如果相同的文件有时被报告为文件系统对象,有时则不是,这将成为您唯一的解释。

【讨论】:

  • 它是 NTFS,但没有符号链接或目录重解析点。
  • 但是,您提出了另一个有趣的可能性。此代码在 VM 内运行。如果虚拟化磁盘报告虚假的瞬时坏块错误,这可能有助于解释问题。
【解决方案2】:

您是在递归执行此操作吗?

如果您进入存档(例如 zip 或 cab 文件),您将看到非文件系统对象。

同样,如果您进入包含 desktop.ini 文件的目录,您可能会看到非文件系统对象(但这取决于 desktop.ini 引用的 COM 对象的作用)。

尽管在这两种情况下,如果您尝试将对象作为文件访问,您会看到未找到错误而不是访问被拒绝。您是否有可能对违规对象没有文件系统权限?

符号链接和重解析点等 NTFS 功能被报告为文件系统对象,因此它们绝对不是问题。

【讨论】:

  • 我们以递归方式执行此操作,但不涉及 zip 文件。一些涉及的文件夹确实包含“desktop.ini”文件,但它们的内容很无聊,按照覆盖显示名称的顺序。当然,我们可能没有访问文件的权限,但是没有权限的文件系统对象仍然是文件系统对象。
猜你喜欢
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多