Расширение оболочки проводника Windows: рекурсивное удаление через ITransferSource :: RemoveItem?

Я реализую расширение оболочки Windows Explorer для сетевой файловой системы в Windows 7, и у меня возникла проблема при реализации функции удаления.

Скажем, моя иерархия удаленной файловой системы выглядит следующим образом:

Dir1
+-Dir2
| +-A
| +-B
+-C

Насколько я понимаю, вам нужно реализовать ITransferSource::RemoveItem (что я и сделал), но я ожидал, что сначала меня вызовут рекурсивно из самого дальнего дочернего элемента в дереве файловой системы (т.е. рекурсивный обход в глубину):

(A, B, Dir2, C, Dir1)

Что происходит, так это то, что меня сначала вызывают для корня, а затем для каждого дочернего элемента, итеративно:

(Dir1, C, Dir2, A, B)

Для меня это немного странно, поскольку оболочка уже рекурсивно перебирает все удаляемые элементы, чтобы показать индикатор выполнения операции (диалоговое окно «обнаружение элементов»). Моя удаленная файловая система не поддерживает удаление непустых каталогов; Насколько мне известно, локальная файловая система в Windows имеет такое же ограничение. Мне не удалось найти на MSDN подсказок об изменении порядка итераций.

Я предполагаю, что фактический порядок итераций зависит от порядка создания элементов в файловой системе.

При реализации этого метода интерфейса вы можете вернуть COPYENGINE_S_DONT_PROCESS_CHILDREN, если вы выполняете рекурсию и удаляете целые деревья самостоятельно, но я думаю, что это не позволит пользователю отменить выполняющееся удаление (как это сделала бы стандартная оболочка проводника). Я считаю это неоптимальным решением, но, возможно, его придется применить, если я не найду лучшего решения.

Моя первая мысль заключалась в том, чтобы поставить в очередь запросы на удаление непустых каталогов на потом, но я не думаю, что это сработает, потому что расширение не будет знать, когда операция удаления для всех дочерних каталогов будет завершена. Я мог бы также создать поток для удаления этих элементов «позже», но это почти наверняка вызовет странное необъяснимое поведение и сбои.

Итак, я предполагаю, что мой вопрос: как правильно реализовать операцию удаления в расширении оболочки Windows 7?

PS: как вы, наверное, догадались, расширения оболочки Windows - это для меня совершенно новая тема, поэтому заранее прошу прощения, если вопрос не завершен; Я уточню свой вопрос по мере необходимости.

Спасибо!


person Benoit Miller    schedule 30.09.2011    source источник
comment
Я ничего об этом не знаю, но в ITransferSource есть пара методов, которые, кажется, предназначены именно для этой цели: EnterFolder и LeaveFolder.   -  person Luke    schedule 01.10.2011
comment
Эй, это работает! Он не фиксирует порядок итераций, но обратные вызовы EnterFolder и LeaveFolder вызываются так, как я ожидал (Enter Dir1, Enter Dir2, Leave Dir2, Leave Dir1). Вы должны добавить этот комментарий в качестве ответа, чтобы я мог отдать вам должное и закрыть вопрос.   -  person Benoit Miller    schedule 03.10.2011


Ответы (1)


Из документации это выглядит как EnterFolder и LeaveFolder.

person Luke    schedule 03.10.2011
comment
Еще раз спасибо, я пропустил эти методы в документе. Это не совсем то, что я хотел, но я определенно могу с этим поработать. - person Benoit Miller; 03.10.2011
comment
@BenoitMiller: Как ты их использовал? У меня почти такой же случай, и мне не вызываются ни EnterFolder, ни LeaveFolder. Более того, я не могу понять, как их вызов может помочь в удалении. Не могли бы вы немного расшириться? - person Raphaël Saint-Pierre; 11.11.2011
comment
В моем обработчике RemoveItem, если удаление не удается, я сохраняю путь к папке в другом месте (структура состояний, связанная с основным объектом, который я просматриваю, а не с PIDL). Затем, когда вызывается LeaveFolder, если путь совпадает с тем, который я сохранил ранее, я знаю, что мне нужно повторить запрос на удаление. - person Benoit Miller; 11.11.2011
comment
У меня не было проблем с вызовом этих методов, я просто возвращаю указатель на интерфейс ITransferSource при вызове IShellFolder2 :: CreateViewObject. Затем, когда вызывается ITransferSource :: LeaveFolder, я ищу свой собственный ptr для переданного шелл-элемента и вызываю функцию, которая выполняет любые ожидающие операции (в моем случае удаление, которое не удалось). - person Benoit Miller; 11.11.2011