2011-05-15 15 views
12

Estoy haciendo una aplicación como explorador para buscar archivos almacenados en mi computadora. Mi aplicación estará en la vista "Icono". La pregunta es: ¿Cómo mostrar el ícono de un archivo exe?Obtener iconos de programa

Respuesta

19

Hay varias formas de hacerlo. La más sencilla es probablemente para agregar una referencia a System.Drawing y tomar ventaja del método 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()); 
} 

Otra opción, si usted no desea utilizar System.Drawing, es obtener el icono de la API SHGetFileInfo. Es más difícil, pero también mucho más flexible; por ejemplo, puede obtener el ícono de un archivo que no existe, basado en la extensión (por supuesto, para un ejecutable no es muy útil, ya que devolvería el ícono predeterminado para los archivos ejecutables).

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 

Otra ventaja de este enfoque es que también se puede obtener el icono de un directorio (véase la última edición en el código), lo cual no es posible con Icon.ExtractAssociatedIcon

+6

OMG que existe. –

+0

¿Esta característica existe en WPF? – Cobold

+0

¿Qué característica? Icon.ExtractAssociatedIcon? No es parte de WPF en sí, pero está en .NET Framework. System.Drawing es solo un contenedor para GDI –

Cuestiones relacionadas