2018-05-29 (火)
[WPF] C# 指定したファイルのアイコンを表示する
Windows API Code Packを使用してアイコンを取得して画面表示します。
ローカルファイルの場合は、System.Drawing.Icon.ExtractAssociatedIconで取得することもできますが、UNC(’\‘から始まるパス)は例外になります。
環境
- Windows 10 Pro 64bit 1709
- Visual Studio Community 2017 15.5.7
- .NET Framework 4.6.1
- C# 7.0
- Windows API Code Pack - Core 1.1.2
- Windows API Code Pack - Shell 1.1.1
https://github.com/aybe/Windows-API-Code-Pack-1.1
NuGetから取得します。
PM> Install-Package WindowsAPICodePack-Core
PM> Install-Package WindowsAPICodePack-Shell
結果
ファイルのアイコン取得
MainWindow.xaml
<Grid>
<Image Name="IconImage" Stretch="None" />
</Grid>
MainWindow.xaml.cs
using Microsoft.WindowsAPICodePack.Shell;
public MainWindow()
{
InitializeComponent();
using (var file = ShellFile.FromFilePath(@"C:\Sample.lnk"))
{
file.Thumbnail.FormatOption = ShellThumbnailFormatOption.IconOnly;
IconImage.Source = file.Thumbnail.BitmapSource; // 256x256
// IconImage.Source = file.Thumbnail.SmallBitmapSource; // 16x16
// IconImage.Source = file.Thumbnail.MediumBitmapSource; // 32x32
// IconImage.Source = file.Thumbnail.LargeBitmapSource; // 48x48
// IconImage.Source = file.Thumbnail.ExtraLargeBitmapSource; // 256x256
}
}
ショートカットのアイコン取得
ショートカットファイル(.lnk)のオーバーレイアイコンを付けて取得したい場合は、以下を使用します。
public MainWindow()
{
InitializeComponent();
IconImage.Source = AssociatedIcon.Create(@"C:\Sample.lnk");
}
実装
ショートカットのアイコン取得は、shell32.dll
を使用します。
using System;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
static class AssociatedIcon
{
[DllImport("shell32.dll", EntryPoint = "ExtractAssociatedIcon")]
private static extern IntPtr ExtractAssociatedIcon
(
IntPtr hInst,
[MarshalAs(UnmanagedType.LPStr)] string lpIconPath,
ref int lpiIcon
);
[DllImport("user32.dll")]
private static extern long DestroyIcon(IntPtr hIcon);
public BitmapSource Create(string path)
{
IntPtr hInst = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
int lpiIcon = 0;
IntPtr hIcon = ExtractAssociatedIcon(hInst, path, ref lpiIcon);
try
{
var icon = Icon.FromHandle(hIcon);
return Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DestroyIcon(hIcon);
}
}
}
その他の方法
以下のような手軽な方法もあります。
ただし、UNC(\\
から始まるパス)のファイルを指定すると例外になるため、使用用途に注意してください。
using System.Windows.Interop;
using System.Windows.Media.Imaging;
public MainWindow()
{
InitializeComponent();
// UNCのファイル(new Uri(path).IsUnc == true)の場合は例外になる
var path = @"C:\Sample.exe";
var icon = System.Drawing.Icon.ExtractAssociatedIcon(path);
var source = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
感謝
- アプリケーションに関連づけられたアイコンを取得する - Programming/Tips - 総武ソフトウェア推進所
- ファイルに関連付けられたアイコンのパスを取得したい
- (.Net)Icon.ExtractAssociatedIcon メソッドにやられた : old_3流プログラマのメモ書き
- ファイルに関連付けられたアイコンの取得: C#研究所
- ExtractAssociatedIconでネットワーク上のファイルのICONが取得できない
- pinvoke.net: ExtractAssociatedIcon (shell32)
- ExtractAssociatedIcon function (Windows)
2018-05-29 (火)
関連記事
新着記事