Я реализовал алгоритм обхода каталога для оболочки Windows, используя IShellItem
, IShellFolder
, IStorage
, IStream
и т. Д. Все хорошо.Я даже могу ходить в файлах расширений пространства имен оболочки (например, .zip
).
Однако у меня возникают проблемы с извлечением (обычных) размеров файлов, когда файлы используются какой-либо другой программой с эксклюзивным доступом.
AFAIK, нет ничего, кроме структуры STATSTG
, которая дает больше информации, чем имя файла.По сути, есть 3 способа получить STATSTG
для IShellItem
:
- Итерация с использованием
IEnumSTATSTG
вместо IEnumIDList
.Вместо того, чтобы вызывать IShellFolder::EnumObjects()
, получите IStorage
для папки и вызовите IStorage::EnumElements()
.Теперь вы получаете STATSTG
структуры напрямую. - Получите
IStorage
для IShellItem
и вызовите IStorage::Stat()
. - Получите
IStream
для IShellItem
и вызовите IStream::Stat()
.
Я бы очень хотел использовать # 1, потому что это дало бы мне всю необходимую информацию.Однако я не могу заставить его перечислять содержимое папки.Я успешно извлек IStorage
для папки: он сам по себе Stat()
дает мне правильное имя папки.Я успешно извлек IEnumSTATSTG
, но первый вызов Next(1, &item, NULL)
возвращает S_FALSE
и завершает перечисление.
Я бы отказался использовать # 2, так как он все еще не так плох, но извлекает IStorage
для обычных файлов на диске выдает ошибку, используя IShellItem::BindToHandler(0, BHID_Storage, ...)
и IShellFolder::BindToStorage(child, ...)
.
Я наконец-то пробовал # 3, хотя это просто кажется неправильным и успешно, пока файлы не используются с эксклюзивнымдоступ из другой программы.
Я немного погуглил и нашел несколько фрагментов кода, которые используют подход № 3.
Вопрос : Может кто-нибудь объяснить, как ядолжен получить файл STATSTG
без использования подхода № 3?
Должен ли подход № 1 работать, или реализация IStorage
для обычных папок просто не дает списков?Должен ли подход №2 работать или реализация IStorage
просто не реализована для обычных файлов?
Среда : 32-разрядная версия Windows Vista Ultimate, Visual Studio 2008 Express.Используя C ++, без ATL, все пользовательские COM-оболочки (собственные, могут быть соответствующим образом изменены, если предположить, что что-то там не так).