Как получить значки общих типов файлов в С#?

Как видно из Этот ТАК вопрос о получении значков для распространенных типов файлов, это довольно Программа Windows может получить значки для зарегистрированного типа файла с помощью C++ Shell API. Эти значки могут существовать или отсутствовать на диске — например, мы хотели создать собственный файловый браузер и отображать связанный с системой значок с файлом.

Есть ли собственный способ С# для получения значков для различных типов файлов (и если да, то как) или это должно быть сделано через PInvoke с API-интерфейсом оболочки?

И в качестве продолжения, если есть собственный способ сделать это .NET, есть ли кросс-платформенный способ сделать это?


person Robert P    schedule 05.03.2009    source источник
comment
Просто обратитесь к этой статье: codeproject.com/KB/cs/GetFileTypeAndIcon.aspx   -  person imzrh    schedule 16.12.2011


Ответы (6)


Взгляните на: http://mvolo.com/display-pretty-file-icons-in-your-aspnet-applications-with-iconhandler/

Это не самое чистое решение, но оно работает. В противном случае попробуйте получить библиотеку значков, основанную на типе mime или расширении файла.

person Gabriël    schedule 05.03.2009
comment
Его версия 2.0 выглядит еще интереснее. Жаль, что кажется, что единственные решения связаны с p/invoke. - person Robert P; 06.03.2009
comment
Ссылка не работает. Получение 403 запрещено. попробуйте mvolo.com/ - person IronManMark20; 27.05.2015

Один из моих старых проектов с открытым исходным кодом включает Icon class, который делает именно это, не стесняйтесь копировать его, учитывая возраст, когда я помещал этот файл в общественное достояние, в любом случае, это просто PInvoke по большей части.

Чтобы получить значок, который вы используете, например:

Icon zipIcon = BlackFox.Win32.Icons.IconFromExtension(".zip", SystemIconSize.Small);

Полный образец:

using System;
using System.Windows.Forms;
using BlackFox.Win32;
using System.Drawing;

class Program
{
    static void Main(string[] args)
    {
        PictureBox pict = new PictureBox();
        pict.Image = Icons.IconFromExtension(".zip", Icons.SystemIconSize.Large).ToBitmap();
        pict.Dock = DockStyle.Fill;
        pict.SizeMode = PictureBoxSizeMode.CenterImage;

        Form form = new Form();
        form.Controls.Add(pict);

        Application.Run(form);        
    }
}

Библиотека :

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.Collections.Generic;

namespace BlackFox.Win32
{
    public static class Icons
    {
        #region Custom exceptions class

        public class IconNotFoundException : Exception
        {
            public IconNotFoundException(string fileName, int index)
                : base(string.Format("Icon with Id = {0} wasn't found in file {1}", index, fileName))
            {
            }
        }

        public class UnableToExtractIconsException : Exception
        {
            public UnableToExtractIconsException(string fileName, int firstIconIndex, int iconCount)
                : base(string.Format("Tryed to extract {2} icons starting from the one with id {1} from the \"{0}\" file but failed", fileName, firstIconIndex, iconCount))
            {
            }
        }

        #endregion

        #region DllImports

        /// <summary>
        /// Contains information about a file object. 
        /// </summary>
        struct SHFILEINFO
        {
            /// <summary>
            /// Handle to the icon that represents the file. You are responsible for
            /// destroying this handle with DestroyIcon when you no longer need it. 
            /// </summary>
            public IntPtr hIcon;

            /// <summary>
            /// Index of the icon image within the system image list.
            /// </summary>
            public IntPtr iIcon;

            /// <summary>
            /// Array of values that indicates the attributes of the file object.
            /// For information about these values, see the IShellFolder::GetAttributesOf
            /// method.
            /// </summary>
            public uint dwAttributes;

            /// <summary>
            /// String that contains the name of the file as it appears in the Microsoft
            /// Windows Shell, or the path and file name of the file that contains the
            /// icon representing the file.
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;

            /// <summary>
            /// String that describes the type of file.
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        };

        [Flags]
        enum FileInfoFlags : int
        {
            /// <summary>
            /// Retrieve the handle to the icon that represents the file and the index 
            /// of the icon within the system image list. The handle is copied to the 
            /// hIcon member of the structure specified by psfi, and the index is copied 
            /// to the iIcon member.
            /// </summary>
            SHGFI_ICON = 0x000000100,
            /// <summary>
            /// Indicates that the function should not attempt to access the file 
            /// specified by pszPath. Rather, it should act as if the file specified by 
            /// pszPath exists with the file attributes passed in dwFileAttributes.
            /// </summary>
            SHGFI_USEFILEATTRIBUTES = 0x000000010
        }

        /// <summary>
        ///     Creates an array of handles to large or small icons extracted from
        ///     the specified executable file, dynamic-link library (DLL), or icon
        ///     file. 
        /// </summary>
        /// <param name="lpszFile">
        ///     Name of an executable file, DLL, or icon file from which icons will
        ///     be extracted.
        /// </param>
        /// <param name="nIconIndex">
        ///     <para>
        ///         Specifies the zero-based index of the first icon to extract. For
        ///         example, if this value is zero, the function extracts the first
        ///         icon in the specified file.
        ///     </para>
        ///     <para>
        ///         If this value is �1 and <paramref name="phiconLarge"/> and
        ///         <paramref name="phiconSmall"/> are both NULL, the function returns
        ///         the total number of icons in the specified file. If the file is an
        ///         executable file or DLL, the return value is the number of
        ///         RT_GROUP_ICON resources. If the file is an .ico file, the return
        ///         value is 1. 
        ///     </para>
        ///     <para>
        ///         Windows 95/98/Me, Windows NT 4.0 and later: If this value is a 
        ///         negative number and either <paramref name="phiconLarge"/> or 
        ///         <paramref name="phiconSmall"/> is not NULL, the function begins by
        ///         extracting the icon whose resource identifier is equal to the
        ///         absolute value of <paramref name="nIconIndex"/>. For example, use -3
        ///         to extract the icon whose resource identifier is 3. 
        ///     </para>
        /// </param>
        /// <param name="phIconLarge">
        ///     An array of icon handles that receives handles to the large icons
        ///     extracted from the file. If this parameter is NULL, no large icons
        ///     are extracted from the file.
        /// </param>
        /// <param name="phIconSmall">
        ///     An array of icon handles that receives handles to the small icons
        ///     extracted from the file. If this parameter is NULL, no small icons
        ///     are extracted from the file. 
        /// </param>
        /// <param name="nIcons">
        ///     Specifies the number of icons to extract from the file. 
        /// </param>
        /// <returns>
        ///     If the <paramref name="nIconIndex"/> parameter is -1, the
        ///     <paramref name="phIconLarge"/> parameter is NULL, and the
        ///     <paramref name="phiconSmall"/> parameter is NULL, then the return
        ///     value is the number of icons contained in the specified file.
        ///     Otherwise, the return value is the number of icons successfully
        ///     extracted from the file. 
        /// </returns>
        [DllImport("Shell32", CharSet = CharSet.Auto)]
        extern static int ExtractIconEx(
            [MarshalAs(UnmanagedType.LPTStr)] 
            string lpszFile,
            int nIconIndex,
            IntPtr[] phIconLarge,
            IntPtr[] phIconSmall,
            int nIcons);

        [DllImport("Shell32", CharSet = CharSet.Auto)]
        extern static IntPtr SHGetFileInfo(
            string pszPath,
            int dwFileAttributes,
            out SHFILEINFO psfi,
            int cbFileInfo,
            FileInfoFlags uFlags);

        #endregion

        /// <summary>
        /// Two constants extracted from the FileInfoFlags, the only that are
        /// meaningfull for the user of this class.
        /// </summary>
        public enum SystemIconSize : int
        {
            Large = 0x000000000,
            Small = 0x000000001
        }

        /// <summary>
        /// Get the number of icons in the specified file.
        /// </summary>
        /// <param name="fileName">Full path of the file to look for.</param>
        /// <returns></returns>
        static int GetIconsCountInFile(string fileName)
        {
            return ExtractIconEx(fileName, -1, null, null, 0);
        }

        #region ExtractIcon-like functions

        public static void ExtractEx(string fileName, List<Icon> largeIcons,
            List<Icon> smallIcons, int firstIconIndex, int iconCount)
        {
            /*
             * Memory allocations
             */

            IntPtr[] smallIconsPtrs = null;
            IntPtr[] largeIconsPtrs = null;

            if (smallIcons != null)
            {
                smallIconsPtrs = new IntPtr[iconCount];
            }
            if (largeIcons != null)
            {
                largeIconsPtrs = new IntPtr[iconCount];
            }

            /*
             * Call to native Win32 API
             */

            int apiResult = ExtractIconEx(fileName, firstIconIndex, largeIconsPtrs, smallIconsPtrs, iconCount);
            if (apiResult != iconCount)
            {
                throw new UnableToExtractIconsException(fileName, firstIconIndex, iconCount);
            }

            /*
             * Fill lists
             */

            if (smallIcons != null)
            {
                smallIcons.Clear();
                foreach (IntPtr actualIconPtr in smallIconsPtrs)
                {
                    smallIcons.Add(Icon.FromHandle(actualIconPtr));
                }
            }
            if (largeIcons != null)
            {
                largeIcons.Clear();
                foreach (IntPtr actualIconPtr in largeIconsPtrs)
                {
                    largeIcons.Add(Icon.FromHandle(actualIconPtr));
                }
            }
        }

        public static List<Icon> ExtractEx(string fileName, SystemIconSize size,
            int firstIconIndex, int iconCount)
        {
            List<Icon> iconList = new List<Icon>();

            switch (size)
            {
                case SystemIconSize.Large:
                    ExtractEx(fileName, iconList, null, firstIconIndex, iconCount);
                    break;

                case SystemIconSize.Small:
                    ExtractEx(fileName, null, iconList, firstIconIndex, iconCount);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("size");
            }

            return iconList;
        }

        public static void Extract(string fileName, List<Icon> largeIcons, List<Icon> smallIcons)
        {
            int iconCount = GetIconsCountInFile(fileName);
            ExtractEx(fileName, largeIcons, smallIcons, 0, iconCount);
        }

        public static List<Icon> Extract(string fileName, SystemIconSize size)
        {
            int iconCount = GetIconsCountInFile(fileName);
            return ExtractEx(fileName, size, 0, iconCount);
        }

        public static Icon ExtractOne(string fileName, int index, SystemIconSize size)
        {
            try
            {
                List<Icon> iconList = ExtractEx(fileName, size, index, 1);
                return iconList[0];            
            }
            catch (UnableToExtractIconsException)
            {
                throw new IconNotFoundException(fileName, index);
            }
        }

        public static void ExtractOne(string fileName, int index,
            out Icon largeIcon, out Icon smallIcon)
        {
            List<Icon> smallIconList = new List<Icon>();
            List<Icon> largeIconList = new List<Icon>();
            try
            {
                ExtractEx(fileName, largeIconList, smallIconList, index, 1);
                largeIcon = largeIconList[0];
                smallIcon = smallIconList[0];
            }
            catch (UnableToExtractIconsException)
            {
                throw new IconNotFoundException(fileName, index);
            }
        }

        #endregion

        //this will look throw the registry 
        //to find if the Extension have an icon.
        public static Icon IconFromExtension(string extension,
                                                SystemIconSize size)
        {
            // Add the '.' to the extension if needed
            if (extension[0] != '.') extension = '.' + extension;

            //opens the registry for the wanted key.
            RegistryKey Root = Registry.ClassesRoot;
            RegistryKey ExtensionKey = Root.OpenSubKey(extension);
            ExtensionKey.GetValueNames();
            RegistryKey ApplicationKey =
                Root.OpenSubKey(ExtensionKey.GetValue("").ToString());

            //gets the name of the file that have the icon.
            string IconLocation =
                ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString();
            string[] IconPath = IconLocation.Split(',');

            if (IconPath[1] == null) IconPath[1] = "0";
            IntPtr[] Large = new IntPtr[1], Small = new IntPtr[1];

            //extracts the icon from the file.
            ExtractIconEx(IconPath[0],
                Convert.ToInt16(IconPath[1]), Large, Small, 1);
            return size == SystemIconSize.Large ?
                Icon.FromHandle(Large[0]) : Icon.FromHandle(Small[0]);
        }

        public static Icon IconFromExtensionShell(string extension, SystemIconSize size)
        {
            //add '.' if nessesry
            if (extension[0] != '.') extension = '.' + extension;

            //temp struct for getting file shell info
            SHFILEINFO fileInfo = new SHFILEINFO();

            SHGetFileInfo(
                extension,
                0,
                out fileInfo,
                Marshal.SizeOf(fileInfo),
                FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_USEFILEATTRIBUTES | (FileInfoFlags)size);

            return Icon.FromHandle(fileInfo.hIcon);
        }

        public static Icon IconFromResource(string resourceName)
        {
            Assembly assembly = Assembly.GetCallingAssembly();

            return new Icon(assembly.GetManifestResourceStream(resourceName));
        }

        /// <summary>
        /// Parse strings in registry who contains the name of the icon and
        /// the index of the icon an return both parts.
        /// </summary>
        /// <param name="regString">The full string in the form "path,index" as found in registry.</param>
        /// <param name="fileName">The "path" part of the string.</param>
        /// <param name="index">The "index" part of the string.</param>
        public static void ExtractInformationsFromRegistryString(
            string regString, out string fileName, out int index)
        {
            if (regString == null)
            {
                throw new ArgumentNullException("regString");
            }
            if (regString.Length == 0)
            {
                throw new ArgumentException("The string should not be empty.", "regString");
            }

            index = 0;
            string[] strArr = regString.Replace("\"", "").Split(',');
            fileName = strArr[0].Trim();
            if (strArr.Length > 1)
            {
                int.TryParse(strArr[1].Trim(), out index);
            }
        }

        public static Icon ExtractFromRegistryString(string regString, SystemIconSize size)
        {
            string fileName;
            int index;
            ExtractInformationsFromRegistryString(regString, out fileName, out index);
            return ExtractOne(fileName, index, size);
        }
    }
}
person Julien Roncaglia    schedule 05.03.2009
comment
Кажется, что SO довольно хорошо справляется с копированием пасты из полного файла .cs, интересно знать. - person Julien Roncaglia; 06.03.2009
comment
@VirtualBlackFox: Вы подразумеваете, что это спагетти-код? (стоны) - person Daniel LeCheminant; 06.03.2009
comment
@Daniel: Нет ^_^ просто это просто большая копия/вставка полного файла: D и ТАК, кажется, берет его, раскрашивает и отображает без проблем. - person Julien Roncaglia; 06.03.2009
comment
Конечно, единственная проблема заключается в том, что это решение не только для .NET... вам нужно использовать pInvoke. :( Но эй, это работает :) - person Robert P; 21.06.2011
comment
Что ж, Icon -> Bitmap par можно преобразовать в чистый C# с помощью парсера файлов .ico, но операционная система предоставляет это бесплатно и совершенно удобным способом (пока вы ориентируетесь на платформу Windows, но тогда зачем использовать .ico в другом месте). - person Julien Roncaglia; 23.06.2011
comment
Что касается части расширения → значка, Microsoft не рекомендует запрашивать реестр напрямую, поскольку они могли (что уже делали с WoW64) изменять его между версиями или пакетами обновления, в то время как API, предлагаемый оболочкой, не должен меняться. Тогда pInvoke довольно естественно вызывает оболочку, поскольку нет управляемого интерфейса для оболочки, включенной в Windows (или любую другую большую ОС). - person Julien Roncaglia; 23.06.2011

Я уверен, что вы уже нашли решение своих проблем, но для других я внес некоторые изменения в решение VirtualBlackFox.

Просто замените метод IconFromExtension...

public static Icon IconFromExtension(string extension,
                                            SystemIconSize size)
    {
        // Add the '.' to the extension if needed
        if (extension[0] != '.') extension = '.' + extension;

        //opens the registry for the wanted key.
        RegistryKey Root = Registry.ClassesRoot;
        RegistryKey ExtensionKey = Root.OpenSubKey(extension);
        ExtensionKey.GetValueNames();
        RegistryKey ApplicationKey =
            Root.OpenSubKey(ExtensionKey.GetValue("").ToString());

        RegistryKey CurrentVer = null;
        try
        {
            CurrentVer = Root.OpenSubKey(ApplicationKey.OpenSubKey("CurVer").GetValue("").ToString());
        }
        catch (Exception ex)
        {
            //current version not found... carry on without it?
        }

        if (CurrentVer != null)
            ApplicationKey = CurrentVer;

        //gets the name of the file that have the icon.
        string IconLocation =
            ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString();
        string[] IconPath = IconLocation.Split(',');


        IntPtr[] Large = null;
        IntPtr[] Small = null;
        int iIconPathNumber = 0;

        if (IconPath.Length > 1)
            iIconPathNumber = 1;
        else
            iIconPathNumber = 0;


        if (IconPath[iIconPathNumber] == null) IconPath[iIconPathNumber] = "0";
        Large = new IntPtr[1];
        Small = new IntPtr[1];



        //extracts the icon from the file.
        if (iIconPathNumber > 0)
        {
            ExtractIconEx(IconPath[0],
                Convert.ToInt16(IconPath[iIconPathNumber]), Large, Small, 1);
        }
        else
        {
            ExtractIconEx(IconPath[0],
                Convert.ToInt16(0), Large, Small, 1);
        }


        return size == SystemIconSize.Large ?
            Icon.FromHandle(Large[0]) : Icon.FromHandle(Small[0]);
    }
person Community    schedule 28.08.2009

Icon.ExtractAssociatedIcon() не поможет. Как указано в MSDN, он извлекает только значки < strong>содержится в файле. Так что создание фиктивных файлов тоже не поможет. Насколько мне известно, вам нужно пройти путь p/invoke, чтобы добраться до этих значков. Вопрос, связанный с этим, - this. MaLio, кажется, имеет довольно полный пример как получить значки с помощью p/invoke.

Я также не знаю независимого от платформы способа сделать это (и я не думаю, что он есть).

Извините, я не мог предоставить вам лучшую новость!

person andyp    schedule 05.03.2009
comment
Спасибо за неприятные новости. :) - person Robert P; 06.03.2009
comment
Icon.ExtractAssociatedIcon(...) отлично работает для меня при получении связанного значка любого файла (не только DLL или EXE). Не уверен, в чем была проблема адыпа, но, возможно, с тех пор метод улучшился. - person HappyNomad; 27.07.2011

Этот класс должен выполнить эту работу. Передайте либо имя файла (с путем), либо имя папки (с путем).

public static class FileIcon
{
    [DllImport("shell32.dll")]
    private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
    [StructLayout(LayoutKind.Sequential)]
    private 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;
    };
    private const uint SHGFI_ICON = 0x100;
    private const uint SHGFI_LARGEICON = 0x0; // 'Large icon
    private const uint SHGFI_SMALLICON = 0x1; // 'Small icon

    public static System.Drawing.Icon GetLargeIcon(string file)
    {
        FileIcon.SHFILEINFO shinfo = new FileIcon.SHFILEINFO();
        IntPtr hImgLarge = FileIcon.SHGetFileInfo(file, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), FileIcon.SHGFI_ICON | FileIcon.SHGFI_LARGEICON);
        return System.Drawing.Icon.FromHandle(shinfo.hIcon);
    }

    public static System.Drawing.Icon GetSmallIcon(string file)
    {
        FileIcon.SHFILEINFO shinfo = new FileIcon.SHFILEINFO();
        IntPtr hImgLarge = FileIcon.SHGetFileInfo(file, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), FileIcon.SHGFI_ICON | FileIcon.SHGFI_SMALLICON);
        return System.Drawing.Icon.FromHandle(shinfo.hIcon);
    }
}
person Tholund    schedule 29.06.2012
comment
Это очень компактно! К сожалению, он по-прежнему не работает только с библиотеками C#. ( - person Robert P; 01.07.2012

Вместо просмотра реестра можно использовать интерфейс IQueryAssociations. Этот интерфейс также можно использовать для получения дополнительной информации о зарегистрированных типах файлов (см., например, тип ASSOCSTR). Ниже я прикрепляю код, который заменяет метод IconFromExtension из решения VirtualBlackFox (части его кода остаются нетронутыми):

public static Icon IconFromExtension(string extension, SystemIconSize size)
  {
     if (extension[0] != '.') extension = '.' + extension;

     object obj;
     shell.AssocCreate(shell.CLSID_QueryAssociations, ref shell.IID_IQueryAssociations, out obj);
     var qa = (shell.IQueryAssociations)obj;
     qa.Init(shell.ASSOCF.INIT_DEFAULTTOSTAR, Convert.ToString(extension), UIntPtr.Zero, IntPtr.Zero);

     var bufSize = 0;
     qa.GetString(shell.ASSOCF.NOTRUNCATE, shell.ASSOCSTR.DEFAULTICON, null, null, ref bufSize);

     var sb = new StringBuilder(bufSize);
     qa.GetString(shell.ASSOCF.NOTRUNCATE, shell.ASSOCSTR.DEFAULTICON, null, sb, ref bufSize);

     if (!String.IsNullOrEmpty(sb.ToString()))
     {
        var iconLocation = sb.ToString();
        var iconPath = iconLocation.Split(',');

        var iIconPathNumber = iconPath.Length > 1 ? 1 : 0;

        if (iconPath[iIconPathNumber] == null) iconPath[iIconPathNumber] = "0";
        var large = new IntPtr[1];
        var small = new IntPtr[1];

        //extracts the icon from the file.
        ExtractIconEx(iconPath[0],
                      iIconPathNumber > 0 ? Convert.ToInt16(iconPath[iIconPathNumber]) : Convert.ToInt16(0),
                      large,
                      small, 1);

        return size == SystemIconSize.Large
                  ? Icon.FromHandle(large[0])
                  : Icon.FromHandle(small[0]);
     }
     return IntPtr.Zero;
  }

В дополнение к вышеприведенному коду нужен класс "shell" - обертка Shell API (ниже он ограничивается AssocCreate и необходимыми типами):

using System;
using System.Runtime.InteropServices;
using System.Text;
#pragma warning disable 1591
// ReSharper disable InconsistentNaming

namespace <put_your_appropriate_namespace_here>
{
   public class shell
   {
      [DllImport("shlwapi.dll")]
      public extern static int AssocCreate(
         Guid clsid,
         ref Guid riid,
         [MarshalAs(UnmanagedType.Interface)] out object ppv);

      [Flags]
      public enum ASSOCF
      {
         INIT_NOREMAPCLSID = 0x00000001,
         INIT_BYEXENAME = 0x00000002,
         OPEN_BYEXENAME = 0x00000002,
         INIT_DEFAULTTOSTAR = 0x00000004,
         INIT_DEFAULTTOFOLDER = 0x00000008,
         NOUSERSETTINGS = 0x00000010,
         NOTRUNCATE = 0x00000020,
         VERIFY = 0x00000040,
         REMAPRUNDLL = 0x00000080,
         NOFIXUPS = 0x00000100,
         IGNOREBASECLASS = 0x00000200,
         INIT_IGNOREUNKNOWN = 0x00000400
      }

      public enum ASSOCSTR
      {
         COMMAND = 1,
         EXECUTABLE,
         FRIENDLYDOCNAME,
         FRIENDLYAPPNAME,
         NOOPEN,
         SHELLNEWVALUE,
         DDECOMMAND,
         DDEIFEXEC,
         DDEAPPLICATION,
         DDETOPIC,
         INFOTIP,
         QUICKTIP,
         TILEINFO,
         CONTENTTYPE,
         DEFAULTICON,
         SHELLEXTENSION
      }

      public enum ASSOCKEY
      {
         SHELLEXECCLASS = 1,
         APP,
         CLASS,
         BASECLASS
      }

      public enum ASSOCDATA
      {
         MSIDESCRIPTOR = 1,
         NOACTIVATEHANDLER,
         QUERYCLASSSTORE,
         HASPERUSERASSOC,
         EDITFLAGS,
         VALUE
      }

      [Guid("c46ca590-3c3f-11d2-bee6-0000f805ca57"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      public interface IQueryAssociations
      {
         void Init(
           [In] ASSOCF flags,
           [In, MarshalAs(UnmanagedType.LPWStr)] string pszAssoc,
           [In] UIntPtr hkProgid,
           [In] IntPtr hwnd);

         void GetString(
           [In] ASSOCF flags,
           [In] ASSOCSTR str,
           [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra,
           [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszOut,
           [In, Out] ref int pcchOut);

         void GetKey(
           [In] ASSOCF flags,
           [In] ASSOCKEY str,
           [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra,
           [Out] out UIntPtr phkeyOut);

         void GetData(
           [In] ASSOCF flags,
           [In] ASSOCDATA data,
           [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra,
           [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] out byte[] pvOut,
           [In, Out] ref int pcbOut);

         void GetEnum(); // not used actually
      }

      public static Guid CLSID_QueryAssociations = new Guid("a07034fd-6caa-4954-ac3f-97a27216f98a");
      public static Guid IID_IQueryAssociations = new Guid("c46ca590-3c3f-11d2-bee6-0000f805ca57");

   }
}

Для пользователей WPF, которым нужен ImageSource:

Замените тип возвращаемого значения с Icon на ImageSource и предложение возврата на:

     var iconPtr = size == SystemIconSize.Large ? large[0] : small[0];
     if (iconPtr != IntPtr.Zero)
     {
        return Imaging.CreateBitmapSourceFromHIcon(
           iconPtr,
           Int32Rect.Empty,
           BitmapSizeOptions.FromEmptyOptions());
     }
person Dariusz Wasacz    schedule 06.11.2012