Пример #1
0
        internal static string?GetShellFileTypeAndIcon(string fileName, bool useExistingFile, IconOptions iconOptions, Action <IntPtr>?useIconHandle)
        {
            Conditions.RequireString(fileName, nameof(fileName));
            Conditions.RequireArgument(
                (iconOptions == IconOptions.None && useIconHandle == null) || (iconOptions != IconOptions.None && useIconHandle != null),
                "The iconOptions and useIconHandle arguments must be compatible.");

            SHFILEINFO info       = default;
            int        cbFileInfo = Marshal.SizeOf(info);
            SHGFI      flags      = SHGFI.TypeName;

            int fileAttributes = 0;

            if (!useExistingFile)
            {
                flags |= SHGFI.UseFileAttributes;
                const int FILE_ATTRIBUTE_NORMAL    = 128;
                const int FILE_ATTRIBUTE_DIRECTORY = 16;

                // http://stackoverflow.com/questions/1599235/how-do-i-fetch-the-folder-icon-on-windows-7-using-shell32-shgetfileinfo
                fileAttributes = iconOptions.HasFlag(IconOptions.Folder) ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
            }

            bool useIcon = iconOptions != IconOptions.None;

            if (useIcon)
            {
                flags |= SHGFI.Icon;

                // The Small and Large options are mutually exclusive.  If they specify neither or both, then we'll default to small.
                if (iconOptions.HasFlag(IconOptions.Small) || !iconOptions.HasFlag(IconOptions.Large))
                {
                    flags |= SHGFI.SmallIcon;
                }
                else
                {
                    flags |= SHGFI.LargeIcon;
                }

                if (iconOptions.HasFlag(IconOptions.ShellSize))
                {
                    flags |= SHGFI.ShellIconSize;
                }

                if (iconOptions.HasFlag(IconOptions.Open))
                {
                    flags |= SHGFI.OpenIcon;
                }

                if (iconOptions.HasFlag(IconOptions.Shortcut))
                {
                    flags |= SHGFI.LinkOverlay;
                }

                if (iconOptions.HasFlag(IconOptions.Selected))
                {
                    flags |= SHGFI.Selected;
                }
            }

            string?result = null;

            if (SHGetFileInfo(fileName, fileAttributes, out info, (uint)cbFileInfo, flags) != IntPtr.Zero)
            {
                result = info.szTypeName;
                if (useIcon && useIconHandle != null)
                {
                    // The caller has to make a copy (e.g., Icon.FromHandle(hIcon).Clone()).
                    useIconHandle(info.hIcon);
                    DestroyIcon(info.hIcon);
                }
            }

            return(result);
        }