Как установить отображаемое имя папки, например, с помощью "SHGetSetFolderCustomSettings()"?
Похоже, SHGetSetFolderCustomSettings позволяет установить значок, всплывающую подсказку, шаблон веб-представления и прочее, но я не смог найти, как установить LocalizedResourceName
в ассоциированном desktop.ini
(см. структуру SHFOLDERCUSTOMSETTINGS).
Поэтому я сейчас пишу desktop.ini
напрямую, однако это сопровождается оговоркой:
Explorer не обновляет свои представления должным образом, даже когда вы говорите ему обновить с помощью F5 или Ctrl + R.
Это то, что я хочу написать, используя Python (хотя не-Python-код должен быть меньшей проблемой):
[.ShellClassInfo]
LocalizedResourceName=My Folder Name
InfoTip=A customized folder
Любые идеи, как установить имя папки и правильно обновить ее в Проводнике?
Я пробовал с SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_PATH, path, path)
, но это не похоже на обновление отображаемого имени (а также с SHCNE_RENAMEFOLDER
, SHCNE_RENAMEITEM
, SHCNE_UPDATEDIR
, SHCNE_UPDATEITEM
).
(Худший подход, вероятно, будет редактировать desktop.ini
дважды... один раз напрямую, затем с этой функцией API... скорее не то, что я хочу).
О том, почему (я думаю, по крайней мере один из вас спросит):
Я храню данные проекта, используя GUID в качестве имен папок.
Однако пользователь должен увидеть понятное имя, которое также можно использовать для сортировки (и, возможно, даже сможет редактировать его, не вмешиваясь во внутреннее имя). Кроме того, низкоуровневая структура файловой системы должна быть обратно совместима с более старыми версиями программного обеспечения.
1 ответ
Используйте простой вызов IShellFolder.SetNameOf:
procedure UpdateLocalizedResourceName(const ADirectory, ANewResourceName: UnicodeString);
var
Desktop: IShellFolder;
Eaten: DWORD;
DirIDList1, Child, NewChild: PItemIDList;
Attr: DWORD;
Folder: IShellFolder;
begin
OleCheck(SHGetDesktopFolder(Desktop));
try
Attr := 0;
OleCheck(Desktop.ParseDisplayName(0, nil, PWideChar(ADirectory), Eaten, DirIDList1, Attr));
try
OleCheck(SHBindToParent(DirIDList1, IShellFolder, Pointer(Folder), Child));
try
OleCheck(Folder.SetNameOf(0, Child, PWideChar(ANewResourceName), SHGDN_INFOLDER, NewChild));
CoTaskMemFree(NewChild);
finally
Folder := nil;
end;
finally
CoTaskMemFree(DirIDList1);
end;
finally
Desktop := nil;
end;
end;
ОБНОВИТЬ
Важное замечание! Параметр LocalizedResourceName должен существовать в desktop.ini перед вызовом UpdateLocalizedResourceName. В противном случае функция SetNameOf завершается ошибкой.