我使用IShellItem
,IShellFolder
,IStorage
,IStream
等为Windows Shell实现了目录步行算法。一切都很好。我甚至可以在shell命名空间扩展(例如.zip
)文件中进行操作。
但是,当某些其他具有独占访问权限的程序使用文件时,我在提取(常规)文件大小时遇到问题。
AFAIK,只有STATSTG
结构提供的信息比文件名更多。基本上有三种方法可以获得STATSTG
IShellItem
的{{1}}。
IEnumSTATSTG
代替IEnumIDList
进行迭代。不要调用IShellFolder::EnumObjects()
,而是获取文件夹的IStorage
并调用IStorage::EnumElements()
。您现在可以直接获得STATSTG
个结构。IStorage
的{{1}}并调用IShellItem
。IStorage::Stat()
的{{1}}并调用IStream
。我真的很想使用#1,因为它会给我所需的所有信息。但是,我无法枚举文件夹内容。我成功提取了文件夹的IShellItem
:它自己的IStream::Stat()
为我提供了正确的文件夹名称。我成功提取了IStorage
,但第一次调用Stat()
会返回IEnumSTATSTG
并终止枚举。
我会回退使用#2,因为它仍然没有那么糟糕,但是为常规磁盘文件提取Next(1, &item, NULL)
会导致使用S_FALSE
和IStorage
同时出错。
我终于尝试了#3虽然它只是平原似乎错了,只要文件不被其他程序独占访问使用它就会成功。
我已经搜索了一下,发现了几个使用方法#3的代码片段。
问题:任何人都可以解释如何在不使用方法#3的情况下获取文件的IShellItem::BindToHandler(0, BHID_Storage, ...)
吗?
是否应该处理#1工作,或者常规文件夹的IShellFolder::BindToStorage(child, ...)
实现是否只生成列表?方法#2应该工作还是STATSTG
实现根本没有为常规文件实现?
环境:Windows Vista Ultimate 32位,Visual Studio 2008 Express。使用C ++,没有ATL,所有自定义COM包装器(内部,可能会适当修改,假设那里有错误)。
答案 0 :(得分:1)
您是否尝试过获取IShellItem2接口,然后查询PKEY_Size属性的值?
答案 1 :(得分:1)
即使接受了答案,也需要做一些事情。
您需要的第一件事是Windows Properties参考。从那里你必须知道你想要进入System.Size。从那里你可以得到两个重要的信息:
System.Size
系统提供的项目文件系统大小,以字节为单位。
shellPKey = PKEY_Size
的所属类别强>
输入 = UInt64
知道它是UInt64
,然后您可以获得IShellItem2
接口,以便使用众多属性获取方法之一:
//Get the IShellItem2 interface out of the IShellItem object
IShellItem2 si2 = shellItem as IShellItem2;
//Get the file fize (in bytes)
UInt64 fileSize;
si2.GetUInt64(PKEY_Size, ref fileSize);