简体   繁体   中英

How to set folder display name with e.g. “SHGetSetFolderCustomSettings()”?

Looks like SHGetSetFolderCustomSettings allows you to set an icon, a tooltip, a web view template and stuff, but I could not find how to set the LocalizedResourceName in the associated desktop.ini (see SHFOLDERCUSTOMSETTINGS structure ).

Therefore I am currently writing to desktop.ini directly, however this comes with a caveat: Explorer does not properly update its views even when you tell it to refresh with F5 or Ctrl+R .

This is what I want to write, using Python (though non-Python code should be less of an issue):

[.ShellClassInfo]
LocalizedResourceName=My Folder Name
InfoTip=A customized folder

Any ideas how to set the folder name and have Explorer properly update it ?

I have tried with SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_PATH, path, path) , but this does not seem to update the display name (and also with SHCNE_RENAMEFOLDER , SHCNE_RENAMEITEM , SHCNE_UPDATEDIR , SHCNE_UPDATEITEM ).

(The worst approach would probably be to edit the desktop.ini twice... once directly, then with that API function... rather not what I want).

About the why (I guess at least one of you will ask):

I am storing project data using GUIDs as folder names.

The user should however see a friendly name that can also be used for sorting (and maybe even be able to edit it without interfering with the internal name). Furthermore, the low-level file system layout should be backwards-compatible with older versions of the software.

Use simple call of 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;

UPDATE

Important notice! LocalizedResourceName parameter must exists in desktop.ini before you call UpdateLocalizedResourceName. Otherwise SetNameOf function fails.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM