WPF/C# ファイルに関連付けられたアプリケーション アイコン画像の取得

検索してみると、時代ごとにやり方があったようで、複数の方法が引っ掛かる。
現時点では最後のサムネイル取得でいいのか?(Windows XPはもういいだろうということで)

System.Drawing.Icon.ExtractAssociatedIcon

  • あ、これまだ試してない…。普通すぎて盲点だった。たぶん小さいアイコン。

SHGetFileInfo() で SHGFI_LARGEICON を指定する

  • コード例は検索すると出てくるので省略。
  • SHGFI_LARGEICONで32x32サイズ。

SHGetFileInfo() → SHGetImageList() で SHIL_EXTRALARGE/SHIL_JUMBO を指定する → IImageList::GetIcon()

SHCreateItemFromParsingName() → IShellItemImageFactory::GetImage()

[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
public static extern void SHCreateItemFromParsingName(
    [In][MarshalAs(UnmanagedType.LPWStr)] string pszPath,
    [In] IntPtr pbc,
    [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid,
    [Out][MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] out IShellItem ppv);

[ComImportAttribute()]
[GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItemImageFactory
{
    void GetImage(
    [In, MarshalAs(UnmanagedType.Struct)] SIZE size,
    [In] SIIGBF flags,
    [Out] out IntPtr phbm);
}

string sourceFile = "C:\xxxxx.txt";
IntPtr hbitmap = IntPtr.Zero;
IShellItem iShellItem = null;
Guid iIdIShellItem = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
SHCreateItemFromParsingName(sourceFile, IntPtr.Zero, iIdIShellItem, out iShellItem);
((IShellItemImageFactory)iShellItem).GetImage(new SIZE(256, 256), 0x0, out hbitmap);