0

Getting file icons commonly this works well with this approach.

But if your path contain any emoji, like this:

♨HotSprings

an exception will be thrown.

Exception in Visual Studio

System.ArgumentException:“Arg_ArgumentException Arg_ParamName_Name”

Does anyone know how to deal with this?

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
Shawn
  • 82
  • 1
  • 6
  • 2
    Please don't include your answer in the question. Please add it as a separate answer. – phuzi Jan 17 '22 at 08:57
  • Please try to provide additional details to highlight exactly what you need. In the future link and/or images might not be available. – Berci Jan 26 '22 at 11:19

1 Answers1

0

Finally I found the solution: SHGetFileInfoW.

https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shgetfileinfow

SHGetFileInfoW can process type LPCWSTR, the unicode emoji can be decode then.


        [Flags]
        public enum ShellGetFileInfoFlags : uint
        {
            /// <summary>
            ///     Modify SHGFI_ICON, causing the function to retrieve the file's large icon. The SHGFI_ICON flag must also be set.
            /// </summary>
            LargeIcon = 0x0,

            /// <summary>
            ///     Modify SHGFI_ICON, causing the function to retrieve the file's small icon. Also used to modify SHGFI_SYSICONINDEX,
            ///     causing the function to return the handle to the system image list that contains small icon images. The SHGFI_ICON
            ///     and/or SHGFI_SYSICONINDEX flag must also be set.
            /// </summary>
            SmallIcon = 0x1,

            /// <summary>
            ///     Retrieve the handle to the icon that represents the file and the index of the icon within the system image list.
            ///     The handle is copied to
            ///     the hIcon member of the structure specified by psfi, and the index is copied to the iIcon member.
            /// </summary>
            Icon = 0x100,

            /// <summary>
            ///     Indicates that the function should not attempt to access the file specified by pszPath. Rather, it
            ///     should act as if the file specified by pszPath exists with the file attributes passed in dwFileAttributes.
            ///     This flag cannot be combined with the SHGFI_ATTRIBUTES, SHGFI_EXETYPE, or SHGFI_PIDL flags.
            /// </summary>
            UseFileAttributes = 0x10
        }

        //Struct used by SHGetFileInfo function
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        protected struct SHFILEINFOW
        {
            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", CharSet = CharSet.Unicode, ExactSpelling = true)]
        protected static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, ShellGetFileInfoFlags uFlags);



        public static BitmapSource GetFolderIcon(string path)
        {
            try
            {
                if (Directory.Exists(path))
                {
                    var shinfo = new SHFILEINFOW();
                    SHGetFileInfoW(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), ShellGetFileInfoFlags.Icon | ShellGetFileInfoFlags.LargeIcon);
                    using var i = System.Drawing.Icon.FromHandle(shinfo.hIcon);
                    return i.ToBitmap().ToBitmapSource();
                }
            }
            catch (Exception e)
            {
                SimpleLogHelper.Fatal(path, e);
            }
            return null;
        }

Shawn
  • 82
  • 1
  • 6