Как я могу получить значок типа файла, который показывает проводник Windows?

Первый вопрос здесь. Я разрабатываю программу на C # (.NET 3.5), которая отображает файлы в виде списка. Я хотел бы иметь "большую иконку" на экране отобразится значок, который Windows Explorer использует для этого типа файла, в противном случае мне придется использовать некоторый существующий код, подобный этому:

        private int getFileTypeIconIndex(string fileName)
    {
        string fileLocation = Application.StartupPath + "\\Quarantine\\" + fileName;
        FileInfo fi = new FileInfo(fileLocation);
        switch (fi.Extension)
        {
            case ".pdf":
                return 1;
            case ".doc": case ".docx": case ".docm": case ".dotx":case ".dotm": case ".dot":case ".wpd": case ".wps":
                return 2;
            default:
                return 0;
        }

    }

Приведенный выше код возвращает целое число, которое используется для выбора значка из списка изображений, который я заполнил некоторыми общими значками. Это работает нормально, но мне нужно добавить каждое расширение под солнцем! Есть ли способ лучше? Спасибо!

 Robse20 сент. 2008 г., 14:36
Я бы рекомендовал использовать кеш.

Ответы на вопрос(4)

Решение Вопроса

Вы можете найти использованиеIcon.ExtractAssociatedIcon гораздо более простой (управляемый) подход, чем использование SHGetFileInfo. Но будьте осторожны: два файла с одинаковым расширением могут иметь разные значки.

 28 мар. 2014 г., 02:38
К сожалению, эта функция имеет много недостатков и ограничений, когда права доступа к файлам / каталогам часто вызывают проблемы, и эту функцию нельзя использовать для сетевых ресурсов. Желательно думать, что Microsoft разработала бы решение .NET, чтобы дополнить необходимость использовать SHGetFileInfo PInvoke. Также убедитесь, что глубина цвета установлена правильно в любом используемом ImageList, потому что иногда это важно для обеспечения того, чтобы значки выглядели так, как будто они пришли не из Windows 3.1.

Я использовал следующее решение из codeproject в одном из недавних моих проектов

Получение (и управление) значков файлов и папок с помощью SHGetFileInfo в C #

Демо-проект довольно понятен, но в основном вам нужно сделать следующее:

private System.Windows.Forms.ListView FileView;

private ImageList _SmallImageList = new ImageList();
private ImageList _LargeImageList = new ImageList();
private IconListManager _IconListManager;

в конструкторе:

_SmallImageList.ColorDepth = ColorDepth.Depth32Bit;
_LargeImageList.ColorDepth = ColorDepth.Depth32Bit;

_SmallImageList.ImageSize = new System.Drawing.Size(16, 16);
_LargeImageList.ImageSize = new System.Drawing.Size(32, 32);

_IconListManager = new IconListManager(_SmallImageList, _LargeImageList);

FileView.SmallImageList = _SmallImageList;
FileView.LargeImageList = _LargeImageList;

и, наконец, когда вы создаете ListViewItem:

ListViewItem item = new ListViewItem(file.Name, _IconListManager.AddFileIcon(file.FullName));

Отлично сработало для меня.

Иконки файлов хранятся в реестре. Это немного запутанно, но работает что-то вроде

Take the file extension and lookup the registry entry for it, for example .DOC Get the default value for that registry setting, "Word.Document.8" Now lookup that value in the registry. Look at the default value for the "Default Icon" registry key, in this case, C:\Windows\Installer{91120000-002E-0000-0000-0000000FF1CE}\wordicon.exe,1 Open the file and get the icon, using any number after the comma as the indexer.

Пример кода приведен наCodeProject

 31 июл. 2012 г., 20:53
Все предполагают, что это относится к файлам в файловой системе, но у вас есть единственный подход, который работает исключительно на основе расширения файла, и это единственный подход, который хорошо работает при построении, скажем, клиента webdav или ftp.
 22 мая 2018 г., 13:10
Хотя это и правильно, обратите внимание, что он может быть переопределен для каждого пользователя в HKEY_CURRENTUSER. Примите это во внимание тоже.

Редактировать:Вот это версия без PInvoke.

[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
    public IntPtr hIcon;
    public IntPtr iIcon;
    public uint dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string szTypeName;
};

public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

[DllImport("User32.dll")]
public static extern int DestroyIcon(IntPtr hIcon);

public static System.Drawing.Icon GetSystemIcon(string sFilename)
{
    //Use this to get the small Icon
    IntPtr hImgSmall; //the handle to the system image list
    //IntPtr hImgLarge; //the handle to the system image list
    APIFuncs.SHFILEINFO shinfo = new APIFuncs.SHFILEINFO();
    hImgSmall = APIFuncs.SHGetFileInfo(sFilename, 0, ref shinfo,
        (uint)Marshal.SizeOf(shinfo), APIFuncs.SHGFI_ICON | APIFuncs.SHGFI_SMALLICON);

    //Use this to get the large Icon
    //hImgLarge = SHGetFileInfo(fName, 0, 
    //  ref shinfo, (uint)Marshal.SizeOf(shinfo), 
    //  Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);

    //The icon is returned in the hIcon member of the shinfo struct
    System.Drawing.Icon myIcon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone();
    DestroyIcon(shinfo.hIcon); // Cleanup
    return myIcon;
}
 19 дек. 2013 г., 18:52
Это хороший ответ, НО вам всегда нужно учитывать ремонтопригодность. Использование любых внешних вызовов всегда должно быть последним средством, поскольку у вас нет гарантии, что они будут работать для разных версий ОС, пакетов обновлений, других приложений и т. Д. Я не говорю «не использую это решение», что я Я имею в виду "рассмотреть вопрос о затратах на решение". Вам ДЕЙСТВИТЕЛЬНО нужны причудливые иконки?

Ваш ответ на вопрос