Открыть список
Как стать автором
Обновить

Как мне узнать, что каталог на самом деле — Корзина?

Разработка под Windows
Перевод
Автор оригинала: Raymond Chen
Вот вопрос, вызванный реальным запросом клиента:

Мне нужна функция, которая по пути определяет, является ли это частью Корзины. Я пробовал использовать SHGetSpecialFolderPath с CSIDL_BITBUCKET, но это не работает, потому что Корзина — виртуальный каталог, который является объединением Корзин со всех дисков.

Клиент пишет, что не хочет жестко прописывать (hard code) слова RECYLCED и RECYCLER — хорошее решение, поскольку эти имена зависят от многого. Я уже писал, что это зависит от файловой системы. Также это зависит от того, обращаются ли к диску локально или удаленно: корзина, доступная через сеть, называется по-другому. Это может зависить от операционной системы, которая установлена у пользователя. Нет, прописывать имена папок корзины в программе — плохая идея.

Структура SHDESCRIPTIONID сообщает немного больше о папке оболочки (shell folder). Вдобавок к «ID описания» (description ID), также она дает CLSID, и именно это важно в данном случае.

#include <windows.h>
#include <shlobj.h>
#include <tchar.h>
#include <stdio.h>

HRESULT
GetFolderDescriptionId(LPCWSTR pszPath, SHDESCRIPTIONID *pdid)
{
HRESULT hr;
LPITEMIDLIST pidl;
if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL,
&pidl, 0, NULL))) {
IShellFolder *psf;
LPCITEMIDLIST pidlChild;
if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder,
(void**)&psf, &pidlChild))) {
hr = SHGetDataFromIDList(psf, pidlChild,
SHGDFIL_DESCRIPTIONID, pdid, sizeof(*pdid));
psf->Release();
}
CoTaskMemFree(pidl);
}
return hr;
}

int __cdecl wmain(int argc, WCHAR **argv)
{
SHDESCRIPTIONID did;
if (SUCCEEDED(GetFolderDescriptionId(argv[1], &did)) &&
did.clsid == CLSID_RecycleBin) {
printf("is a recycle bin\n");
} else {
printf("is not a recycle bin\n");
}
return 0;
}


Функция GetFolderDescriptionId берет путь к папке и превращает в ITEMIDLIST, чтобы вызвать SHGetDataFromIDList и получить SHDESCRIPTIONID. Все что нас волнует — CLSID ли это Корзины, или нет.

C:\> checkrecycle C:\Windows
is not a recycle bin
C:\> checkrecycle C:\RECYCLER\S-1-5-21-2127521184-1604012920-1887927527-72713
is a recycle bin


Конечно, после того как я сказал, как это сделать, мне надо сказать, как этого не делать. Это очередной пример, как у клиента есть проблема, он решает половину и спрашивает совета, как решить другую, не замечая, что он подходит к проблеме с неправильной стороны. В следующий раз мы рассмотрим настоящую проблему клиента.
Теги:the old new thingwindowswinapiкорзина
Хабы: Разработка под Windows
Всего голосов 11: ↑7 и ↓4 +3
Просмотры1.2K

Комментарии 12

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Похожие публикации

Senior .NET Core Developer
до 350 000 ₽IT X100Можно удаленно
Системный администратор (технологии Microsoft)
от 80 000 до 120 000 ₽НПК «Катрен»Новосибирск
Разработчик под iOS (Swift)
от 100 000 ₽eKassirСанкт-Петербург
Системный администратор
от 85 000 ₽ActimindСанкт-Петербург
Разработчик под Android (Kotlin)
от 100 000 ₽eKassirСанкт-Петербург

Лучшие публикации за сутки