Подтвердить что ты не робот

Получить значки программ

Я делаю приложение-проводник для просмотра файлов, хранящихся на моем компьютере. Мое приложение будет в виде "Значок". Возникает вопрос: как отобразить значок EXE файла?

4b9b3361

Ответ 1

Существует несколько способов сделать это. Самый простой способ - добавить ссылку на System.Drawing и воспользоваться методом Icon.ExtractAssociatedIcon:

public static ImageSource GetIcon(string fileName)
{
    Icon icon = Icon.ExtractAssociatedIcon(fileName);
    return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                icon.Handle, 
                new Int32Rect(icon.Width, icon.Height),
                BitmapSizeOptions.FromEmptyOptions());
}

Другой вариант, если вы не хотите использовать System.Drawing, - это получить значок из API SHGetFileInfo. Это сложнее, но и гораздо более гибко; например, вы можете получить значок файла, который не существует, на основе расширения (конечно, для исполняемого файла это не очень полезно, так как оно вернет значок по умолчанию для исполняемых файлов).

public static ImageSource GetIcon(string path, bool smallIcon, bool isDirectory)
{
    // SHGFI_USEFILEATTRIBUTES takes the file name and attributes into account if it doesn't exist
    uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
    if (smallIcon)
        flags |= SHGFI_SMALLICON;

    uint attributes = FILE_ATTRIBUTE_NORMAL;
    if (isDirectory)
        attributes |= FILE_ATTRIBUTE_DIRECTORY;

    SHFILEINFO shfi;
    if (0 != SHGetFileInfo(
                path,
                attributes,
                out shfi,
                (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                flags))
    {
        return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                    shfi.hIcon, 
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
    }
    return null;
}

[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
    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")]
    private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);

private const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040;
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000;

private const uint SHGFI_ICON = 0x000000100;     // get icon
private const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
private const uint SHGFI_TYPENAME = 0x000000400;     // get type name
private const uint SHGFI_ATTRIBUTES = 0x000000800;     // get attributes
private const uint SHGFI_ICONLOCATION = 0x000001000;     // get icon location
private const uint SHGFI_EXETYPE = 0x000002000;     // return exe type
private const uint SHGFI_SYSICONINDEX = 0x000004000;     // get system icon index
private const uint SHGFI_LINKOVERLAY = 0x000008000;     // put a link overlay on icon
private const uint SHGFI_SELECTED = 0x000010000;     // show icon in selected state
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000;     // get only specified attributes
private const uint SHGFI_LARGEICON = 0x000000000;     // get large icon
private const uint SHGFI_SMALLICON = 0x000000001;     // get small icon
private const uint SHGFI_OPENICON = 0x000000002;     // get open icon
private const uint SHGFI_SHELLICONSIZE = 0x000000004;     // get shell size icon
private const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;     // use passed dwFileAttribute

Другим преимуществом этого подхода является то, что он также может получить значок для каталога (см. последнее редактирование в коде), что невозможно при использовании Icon.ExtractAssociatedIcon