Как я могу получить локализованное имя «специальной» папки Windows (корзина и т. Д.)?

StackOverflow https://stackoverflow.com/questions/37053

Вопрос

Я пытаюсь найти «правильный» Windows API для определения локализованного имени «специальных» папок, в частности корзины. Я хочу, чтобы пользователь мог через соответствующее локализованное диалоговое окно запросить у него, хотят ли они отправить файлы в корзину или удалить их напрямую.

В Интернете (и в Stackoverflow) я много раз находил о том, как сделать фактическое удаление, и это кажется достаточно простым, я просто очень хочу иметь возможность локализовать текст.

Это было полезно?

Решение

Прочитайте эту статью для примеров кода и использования:

http://www.codeproject.com/KB/winsdk/SpecialFolders.aspx

Также есть статья на MSDN, которая поможет вам Определите местоположение специальных папок с помощью вызовов API

Другие советы

На самом деле я не нашел статью CodeProject очень полезной, поэтому я решил ответить на этот вопрос с помощью фактического кода, который я использовал для получения локализованного имени корзины.

Этот пример также пытается вести себя правильно в отношении освобождения ресурсов. Любые комментарии приветствуются, особенно если вы заметили ошибку в моем управлении ресурсами!

public static string GetLocalizedRecycleBinName()
{
   IntPtr relative_pidl, parent_ptr, absolute_pidl;

   PInvoke.SHGetFolderLocation(IntPtr.Zero, PInvoke.CSIDL.BitBucket,
         IntPtr.Zero, 0, out absolute_pidl);
   try
   {
      PInvoke.SHBindToParent(absolute_pidl,
            ref PInvoke.Guids.IID_IShellFolder,
            out parent_ptr, out relative_pidl);
      PInvoke.IShellFolder shell_folder =
            Marshal.GetObjectForIUnknown(parent_ptr)
            as PInvoke.IShellFolder;
      // Release() for this object is called at finalization
      if (shell_folder == null)
         return Strings.RecycleBin;

      PInvoke.STRRET strret = new PInvoke.STRRET();
      StringBuilder sb = new StringBuilder(260);
      shell_folder.GetDisplayNameOf(relative_pidl, PInvoke.SHGNO.Normal,
            out strret);
      PInvoke.StrRetToBuf(ref strret, relative_pidl, sb, 260);
      string name = sb.ToString();

      return String.IsNullOrEmpty(name) ? Strings.RecycleBin : name;
   }
   finally { PInvoke.ILFree(absolute_pidl); }
}

static class PInvoke
{
   [DllImport("shell32.dll")]
   public static extern int SHGetFolderLocation(IntPtr hwndOwner,
         CSIDL nFolder, IntPtr hToken, uint dwReserved, out IntPtr ppidl);

   [DllImport("shell32.dll")]
   public static extern int SHBindToParent(IntPtr lpifq, [In] ref Guid riid,
         out IntPtr ppv, out IntPtr pidlLast);

   [DllImport("shlwapi.dll")]
   public static extern Int32 StrRetToBuf(ref STRRET pstr, IntPtr pidl,
         StringBuilder pszBuf, uint cchBuf);

   [DllImport("shell32.dll")]
   public static extern void ILFree([In] IntPtr pidl);

   [ComImport]
   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   [Guid("000214E6-0000-0000-C000-000000000046")]
   public interface IShellFolder
   {
      [PreserveSig]
      Int32 CompareIDs(Int32 lParam, IntPtr pidl1, IntPtr pidl2);
      void ParseDisplayName(IntPtr hwnd, IntPtr pbc, String pszDisplayName,
            UInt32 pchEaten, out IntPtr ppidl, UInt32 pdwAttributes);
      void EnumObjects(IntPtr hwnd, int grfFlags,
            out IntPtr ppenumIDList);
      void BindToObject(IntPtr pidl, IntPtr pbc, [In] ref Guid riid,
            out IntPtr ppv);
      void BindToStorage(IntPtr pidl, IntPtr pbc, [In] ref Guid riid,
            out IntPtr ppv);
      void CreateViewObject(IntPtr hwndOwner, [In] ref Guid riid,
            out IntPtr ppv);
      void GetAttributesOf(UInt32 cidl,
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
         IntPtr[] apidl, ref uint rgfInOut);
      void GetUIObjectOf(IntPtr hwndOwner, UInt32 cidl,
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
         IntPtr[] apidl, [In] ref Guid riid, UInt32 rgfReserved,
         out IntPtr ppv);
      void GetDisplayNameOf(IntPtr pidl, SHGNO uFlags, out STRRET pName);
      void SetNameOf(IntPtr hwnd, IntPtr pidl, string pszName,
            int uFlags, out IntPtr ppidlOut);
   }

   public enum CSIDL
   {
      BitBucket = 0x000a,
   }

   public enum SHGNO
   {
      Normal = 0x0000, ForParsing = 0x8000,
   }

   [StructLayout(LayoutKind.Explicit, Size = 520)]
   public struct STRRETinternal
   {
      [FieldOffset(0)] public IntPtr pOleStr;
      [FieldOffset(0)] public IntPtr pStr;
      [FieldOffset(0)] public uint uOffset;
   }

   [StructLayout(LayoutKind.Sequential)]
   public struct STRRET
   {
      public uint uType;
      public STRRETinternal data;
   }

   public class Guids
   {
      public static Guid IID_IShellFolder =
            new Guid("{000214E6-0000-0000-C000-000000000046}");
   }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top