通过`IShellItem`获取文件大小

And*_*ron 7 c++ windows windows-shell

我已经使用实现了一个目录遍历算法用于在Windows Shell IShellItem,IShellFolder,IStorage,IStream,等一切都很好.我甚至可以在shell命名空间扩展(例如.zip)文件中进行操作.

但是,当某些其他具有独占访问权限的程序使用文件时,我在提取(常规)文件大小时遇到​​问题.

AFAIK,只有STATSTG结构提供了比文件名更多的信息.基本上有3种方法来获取STATSTGa IShellItem:

  1. 迭代使用IEnumSTATSTG而不是IEnumIDList.而不是调用IShellFolder::EnumObjects(),获取IStorage文件夹并调用IStorage::EnumElements().你现在STATSTG直接获得结构.
  2. 获得IStorageIShellItem与调用IStorage::Stat().
  3. 获得IStreamIShellItem与调用IStream::Stat().

我真的很想使用#1,因为它会给我所需的所有信息.但是,我无法枚举文件夹内容.我成功提取了IStorage文件夹:它自己Stat()给了我正确的文件夹名称.我成功提取了IEnumSTATSTG,但第一次调用Next(1, &item, NULL)返回S_FALSE并终止枚举.

我会回退使用#2,因为它仍然没有那么糟糕,但提取IStorage常规磁盘文件会产生使用IShellItem::BindToHandler(0, BHID_Storage, ...)和的错误IShellFolder::BindToStorage(child, ...).

我终于尝试了#3,虽然它只是平原似乎错了,只要文件没有被其他程序独占访问使用它就会成功.

我已经google了一下,发现了几个使用方法#3的代码片段.

问题:任何人都可以解释如何在STATSTG不使用方法#3 的情况下获取文件吗?

方法#1应该工作,还是IStorage常规文件夹的实现根本不生成列表?方法#2应该工作还是实际上IStorage没有为常规文件实现?

环境:Windows Vista Ultimate 32位,Visual Studio 2008 Express.使用C++,没有ATL,所有自定义COM包装器(内部,可以适当修改,假设那里有错误).

Rog*_*mbe 1

您是否尝试过获取 IShellItem2 接口,然后查询 PKEY_Size 属性的值?

  • 事实上,我在 Platform SDK 的 Include 文件夹中查找它,但没有出现。我已经决定使用“IShellFolder2::GetDetailsEx()”,它的工作方式就像一个魅力。它也兼容XP! (2认同)