Однажды разрабатывая приложение возникла потребность получить значок (иконку) из exe-файла средствами C#. И тут возник вопрос: как это сделать? Как извлечь иконку из exe или dll?
Немного погодя стало понятно, что лучше использовать средства WinAPI, обернутые C#. После этого нашел описание в MSDN, какие функции использовать и какие струтуры. Но так как использовать WinAPI мне тяжко, в силу того, что я ну уж очень привык к .NET, то создание полноценного класса забрало у меня много времени. На одном из англоязычных ресурсов нашел помощь в этом вопросе, но к сожалению адрес забыл. Поэтому, чтобы помочь другим искателям данного решения пишу эту статью.
В библиотеке Shell32.dll есть функция SHGetFileInfo, с помощью которой можно получить дескриптор значка. Если быть точнее, то мы передаем в нее некую структуру SHFILEINFO, которая и будет заполнена информацией. Эта структура должна иметь вид:
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero;
iIcon = 0;
dwAttributes = 0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
public string szTypeName;
};
В данной структуре свойство hIcon и будет являться дескриптором нашего значка. А теперь уже мы можем получить наш объект Icon, с которым мы сможем работать привычным нам способом. Используя код System.Drawing.Icon.FromHandle(hIcon) мы получаем объект Icon. Далее можете делать с этим значком что пожелаете.
Для облегчения задачи выкладываю готовый класс, которым я пользуюсь на текущий момент. В нем также имеется метод GetIconFromExeDll, который принимает путь к библитеке или исполняемому файлу и индекс значка в нем и возвращает объект Icon. Циклично используя этот метод можно получить весь список значков хранящихся в файле. Этот класс используется в программе DrivesIcon.