2010-04-23 15 views
20

wiem można wyodrębnić ikonę z plikiem za pomocąPobierz ikonę dla danego rozszerzenia

using (System.Drawing.Icon sysicon = System.Drawing.Icon.ExtractAssociatedIcon(filePath)) 
{ 
    icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
     sysicon.Handle, 
     System.Windows.Int32Rect.Empty, 
     System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); 
} 

Ale jak mogę, bez pliku, uzyskać ikonę dla danego rozszerzenia?

+0

Czy masz na myśli użycie domyślnej ikony, którą okna przypiszą do nowych plików? Ponieważ w takim przypadku zależy to od rozszerzenia pliku. Podaj więcej szczegółów na temat tego, co chcesz. –

Odpowiedz

33

Użyj metody GetFileIcon z this CodeProject artykułu od Paula Inglesa i przekazać .ext jako parametr name.

Sposób GetFileIcon jest owinięcie wokół rodzimej SHGetFileInfo i kopiowane tu dla ilustracji:

public static System.Drawing.Icon GetFileIcon(string name, IconSize size, 
               bool linkOverlay) 
{ 
    Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO(); 
    uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES; 

    if (true == linkOverlay) flags += Shell32.SHGFI_LINKOVERLAY; 


    /* Check the size specified for return. */ 
    if (IconSize.Small == size) 
    { 
     flags += Shell32.SHGFI_SMALLICON ; // include the small icon flag 
    } 
    else 
    { 
     flags += Shell32.SHGFI_LARGEICON ; // include the large icon flag 
    } 

    Shell32.SHGetFileInfo(name, 
     Shell32.FILE_ATTRIBUTE_NORMAL, 
     ref shfi, 
     (uint) System.Runtime.InteropServices.Marshal.SizeOf(shfi), 
     flags); 


    // Copy (clone) the returned icon to a new object, thus allowing us 
    // to call DestroyIcon immediately 
    System.Drawing.Icon icon = (System.Drawing.Icon) 
         System.Drawing.Icon.FromHandle(shfi.hIcon).Clone(); 
    User32.DestroyIcon(shfi.hIcon); // Cleanup 
    return icon; 
} 
+2

+1 dla wnioskowania fu i poprawnej odpowiedzi. –

+2

działa do 32 x 32 pikseli ... nie jest idealny do ... cóż, cokolwiek więcej w dzisiejszych czasach –

19

poniższy kod opiera się również na Paul Ingles solution, ale:

  • użytkowa z WPF (ImageSource zamiast Icon)
  • Ma proste buforowanie
  • Usunięto wszystkie rzeczy związane z katalogów (mam tylko pliki w moim przypadku)
  • refactored użyciu R # wskazówek i owinięte pojedynczej klasy prostego API

ja testowałem to na Windows 7 i Windows XP SP3, to działa zgodnie z oczekiwaniami z dowolnym ciągiem jako fileName.

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.IO; 
using System.Runtime.InteropServices; 
using System.Windows; 
using System.Windows.Interop; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 

/// <summary> 
/// Internals are mostly from here: http://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using 
/// Caches all results. 
/// </summary> 
public static class IconManager 
{ 
    private static readonly Dictionary<string, ImageSource> _smallIconCache = new Dictionary<string, ImageSource>(); 
    private static readonly Dictionary<string, ImageSource> _largeIconCache = new Dictionary<string, ImageSource>(); 
    /// <summary> 
    /// Get an icon for a given filename 
    /// </summary> 
    /// <param name="fileName">any filename</param> 
    /// <param name="large">16x16 or 32x32 icon</param> 
    /// <returns>null if path is null, otherwise - an icon</returns> 
    public static ImageSource FindIconForFilename(string fileName, bool large) 
    { 
     var extension = Path.GetExtension(fileName); 
     if (extension == null) 
      return null; 
     var cache = large ? _largeIconCache : _smallIconCache; 
     ImageSource icon; 
     if (cache.TryGetValue(extension, out icon)) 
      return icon; 
     icon = IconReader.GetFileIcon(fileName, large ? IconReader.IconSize.Large : IconReader.IconSize.Small, false).ToImageSource(); 
     cache.Add(extension, icon); 
     return icon; 
    } 
    /// <summary> 
    /// http://stackoverflow.com/a/6580799/1943849 
    /// </summary> 
    static ImageSource ToImageSource(this Icon icon) 
    { 
     var imageSource = Imaging.CreateBitmapSourceFromHIcon(
      icon.Handle, 
      Int32Rect.Empty, 
      BitmapSizeOptions.FromEmptyOptions()); 
     return imageSource; 
    } 
    /// <summary> 
    /// Provides static methods to read system icons for both folders and files. 
    /// </summary> 
    /// <example> 
    /// <code>IconReader.GetFileIcon("c:\\general.xls");</code> 
    /// </example> 
    static class IconReader 
    { 
     /// <summary> 
     /// Options to specify the size of icons to return. 
     /// </summary> 
     public enum IconSize 
     { 
      /// <summary> 
      /// Specify large icon - 32 pixels by 32 pixels. 
      /// </summary> 
      Large = 0, 
      /// <summary> 
      /// Specify small icon - 16 pixels by 16 pixels. 
      /// </summary> 
      Small = 1 
     } 
     /// <summary> 
     /// Returns an icon for a given file - indicated by the name parameter. 
     /// </summary> 
     /// <param name="name">Pathname for file.</param> 
     /// <param name="size">Large or small</param> 
     /// <param name="linkOverlay">Whether to include the link icon</param> 
     /// <returns>System.Drawing.Icon</returns> 
     public static Icon GetFileIcon(string name, IconSize size, bool linkOverlay) 
     { 
      var shfi = new Shell32.Shfileinfo(); 
      var flags = Shell32.ShgfiIcon | Shell32.ShgfiUsefileattributes; 
      if (linkOverlay) flags += Shell32.ShgfiLinkoverlay; 
      /* Check the size specified for return. */ 
      if (IconSize.Small == size) 
       flags += Shell32.ShgfiSmallicon; 
      else 
       flags += Shell32.ShgfiLargeicon; 
      Shell32.SHGetFileInfo(name, 
       Shell32.FileAttributeNormal, 
       ref shfi, 
       (uint)Marshal.SizeOf(shfi), 
       flags); 
      // Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly 
      var icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone(); 
      User32.DestroyIcon(shfi.hIcon);  // Cleanup 
      return icon; 
     } 
    } 
    /// <summary> 
    /// Wraps necessary Shell32.dll structures and functions required to retrieve Icon Handles using SHGetFileInfo. Code 
    /// courtesy of MSDN Cold Rooster Consulting case study. 
    /// </summary> 
    static class Shell32 
    { 
     private const int MaxPath = 256; 
     [StructLayout(LayoutKind.Sequential)] 
     public struct Shfileinfo 
     { 
      private const int Namesize = 80; 
      public readonly IntPtr hIcon; 
      private readonly int iIcon; 
      private readonly uint dwAttributes; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxPath)] 
      private readonly string szDisplayName; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Namesize)] 
      private readonly string szTypeName; 
     }; 
     public const uint ShgfiIcon = 0x000000100;  // get icon 
     public const uint ShgfiLinkoverlay = 0x000008000;  // put a link overlay on icon 
     public const uint ShgfiLargeicon = 0x000000000;  // get large icon 
     public const uint ShgfiSmallicon = 0x000000001;  // get small icon 
     public const uint ShgfiUsefileattributes = 0x000000010;  // use passed dwFileAttribute 
     public const uint FileAttributeNormal = 0x00000080; 
     [DllImport("Shell32.dll")] 
     public static extern IntPtr SHGetFileInfo(
      string pszPath, 
      uint dwFileAttributes, 
      ref Shfileinfo psfi, 
      uint cbFileInfo, 
      uint uFlags 
      ); 
    } 
    /// <summary> 
    /// Wraps necessary functions imported from User32.dll. Code courtesy of MSDN Cold Rooster Consulting example. 
    /// </summary> 
    static class User32 
    { 
     /// <summary> 
     /// Provides access to function required to delete handle. This method is used internally 
     /// and is not required to be called separately. 
     /// </summary> 
     /// <param name="hIcon">Pointer to icon handle.</param> 
     /// <returns>N/A</returns> 
     [DllImport("User32.dll")] 
     public static extern int DestroyIcon(IntPtr hIcon); 
    } 
} 
+0

Czy można uzyskać ikony Jumbo? –

+0

@ Nighthawk441 Nie jestem pewien, co to jest ikona Jumbo (duża ikona?). Lepiej spróbuj sam. – astef

+0

Dla rekordu: Nie, SHGetFileInfo może powrócić tylko do 32x32 px –

Powiązane problemy