title: How to get the localized special folder name?
body: <p>I use <code>SHGetFileInfo()</code> or <code>GetDisplayNameOf()</code> to get the name of a special folder.</p>
  
  <p>If a localized operating system to change the setting "Current language for non-Unicode programs", these functions return a value "??? ?????????". </p>
  
  <p>This combination of settings encountered by users.</p>
  
  <p>shell32 is not fully unicode compatible?</p>
  
  <pre><code>Shell32.STRRET STRRET;
  STRRET.uType = (uint)Shell32.STRRET_TYPE.STRRET_WSTR;
  if (Windows.S_OK != ishellfolder_parent.GetDisplayNameOf(ptr_pidllast, (uint)Shell32.SHGNO.SHGDN_NORMAL | (uint)Shell32.SHGNO.SHGDN_INFOLDER, out STRRET))
                  return null;
  
  StringBuilder sbuilder = new StringBuilder(260);
  Shell32.StrRetToBuf(ref STRRET, ptr_pidllast, sbuilder, (uint)sbuilder.Capacity);
  </code></pre>
  
  <p>what is wrong?</p>
  
  <p>***added later
  Another example to demonstrate my question:</p>
  
  <pre><code>public static partial class Program
  {
      const Int32 CSIDL_DESKTOP = (0x0000);
      const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
      const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
  
      [StructLayout(LayoutKind.Sequential)]
      public struct SHFILEINFO
      {
          public static int NAMESIZE = 80;
          public IntPtr hIcon;
          public int iIcon;
          public uint dwAttributes;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
          public string szDisplayName;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
          public string szTypeName;
      };
  
      [DllImport("shell32.dll")]
      static extern IntPtr SHGetFileInfo(IntPtr pidl, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
      [DllImport("shell32.dll")]
      public static extern IntPtr SHCloneSpecialIDList(IntPtr hwnd, Int32 CSIDL, bool create);
  
  
      [STAThread]
      static void Main(string[] args)
      {
          IntPtr pidl = SHCloneSpecialIDList(IntPtr.Zero, CSIDL_DESKTOP, false);
          SHFILEINFO shfi = new SHFILEINFO();
          if (IntPtr.Zero != SHGetFileInfo(
                      pidl,
                      0,
                      ref shfi,
                      (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                      SHGFI_PIDL | SHGFI_DISPLAYNAME))
          {
              System.Windows.Forms.MessageBox.Show(shfi.szDisplayName);
          }
  </code></pre>
  
  <p>This code not correct. Some cases wrong return values, described above.
  Can anyone help me with an example of the correct code, fully compatible with Unicode and works with non-default system settings?</p>
  
  <hr>
  
  <p>Thank you all! After some experiments, and found a solution. My error was here:</p>
  
  <pre><code>Shell32.StrRetToBuf(ref STRRET, ptr_pidllast, sbuilder, (uint)sbuilder.Capacity);
  </code></pre>
  
  <p>The signature should be:</p>
  
  <pre><code>[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, EntryPoint="StrRetToBufW")]
  public static extern Int32 StrRetToBufW( ...
  </code></pre>