【问题标题】:Get file icons with Emoji in the file path获取文件路径中带有表情符号的文件图标
【发布时间】:2022-02-12 10:22:34
【问题描述】:

获取文件图标通常效果很好with this approach

但是如果你的路径包含任何表情符号,像这样:

会抛出异常。

System.ArgumentException:“Arg_ArgumentException Arg_ParamName_Name”

有人知道怎么处理吗?

【问题讨论】:

  • 请不要在问题中包含您的答案。请将其添加为单独的答案。
  • 请尝试提供更多详细信息以准确突出您的需求。将来可能无法使用链接和/或图片。

标签: c# unicode emoji


【解决方案1】:

终于找到了解决办法:SHGetFileInfoW。

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

SHGetFileInfoW 可以处理类型 LPCWSTR,然后可以解码 unicode emoji。


        [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;
        }

【讨论】:

  • DllImport 看起来很奇怪。属性不应该在extern函数之上吗?
  • 问题中链接的答案到底有什么区别? DllImportover 似乎也支持 Unicode。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
相关资源
最近更新 更多