пятница, 17 февраля 2012 г.

Некоторые папки двигать нельзя - и вам придётся научиться с этим жить

Это перевод Some known folders cannot be moved, but others can, and you'll just have to accept that. Автор: Реймонд Чен.

Некоторые из "известных папок" оболочки (Shell known folders) могут быть помечены как KF_CATEGORY_FIXED, что делает их неперемещаемыми. И наоборот, если папка файловой системы не является "неподвижной", то она может быть перемещена.

Эта дихотомия представляется простой и недостойной отдельного обсуждения - за исключением того, что у некоторых клиентов иногда возникают проблемы включения этого понятия в своё мировоззрение.
У меня есть код, который вызывает SHSet­Folder­Path, и он работает для большинства папок, но для некоторых значений CSIDL вроде CSIDL_COMMON_APPDATA код завершается с ошибкой E_INVALIDARG. При этом не имеет значения, вызываю ли я его с повышением привилегий или нет. Что я делаю не так?
Разница в том, что CSIDL_COMMON_APPDATA (известная в Новом Мировом Порядке как FOLDERID_ProgramData) помечена как KF_CATEGORY_FIXED, так что её нельзя переместить.
А есть ли способ игнорировать флаг KF_CATEGORY_FIXED и переместить её?
Нет. Она неперемещаема. Извините. Вам просто остаётся принять тот факт, что эта папка не поменяет своё расположение по вашему желанию.

И буквально на следующий день мы получили такой вопрос от совершенно другого клиента:
У нас есть программа, которая следит за "известной папкой", но наш код вылетает, если пользователь меняет расположение папки в то время, пока программа за ней следит. Есть ли какой-нибудь способ сделать так, чтобы пользователь не мог двигать папку?
Если папка может быть перемещена, то вам нужно принять тот факт, что она может быть перемещена. Вы не можете изменить порядок вещей только потому, что это сделает легче жизнь лично вам.

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

Что может сделать программа - зарегистрировать IFile­Is­In­Use для каталога, так что оболочка вызовет её, когда кто-то захочет переместить папку. И тогда, по крайней мере, программа будет знать, когда будут происходить страшные вещи, и подготовиться к ним. Мне сказали, что простой пример использования IFile­Is­In­Use можно найти в SDK Windows 7 SDK в каталоге winui\Shell\AppPlatform\FileIsInUse. И ещё есть старая статья по этой теме в сейчас-уже-не-работающем блоге Shell Revealed.

1 комментарий:

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.

Примечание. Отправлять комментарии могут только участники этого блога.