Reputation:
I have a path of some program (for example explorer), how can I get program icon, convert it to png/jpeg and then display in PictureBox?
I have something like this:
string filePath = "C:\\myfile.exe";
Icon TheIcon = IconFromFilePath(filePath);
if (TheIcon != null) {
// But then I don't know what to do...
}
public Icon IconFromFilePath(string filePath){
Icon programicon = null;
try {
programicon = Icon.ExtractAssociatedIcon(filePath);
}
catch { }
return programicon;
}
I found something similar here. Here is the icon. How I can create 32-bit icon?
Upvotes: 3
Views: 8730
Reputation: 29
The answer from user Alizer is good because the standard Microsoft class System.Drawing.Icon does not give you the icon with the best resolution. To make it easier for yourself and to get a better performance you can use the NuGet package Ico.Reader.
Example code:
var icoReader = new IcoReader();
string filePath = @"C:\myfile.exe";
IcoData icoData = icoReader.Read(filePath);
// Get the image with the best quality from exe file
int preferredIndex = icoData.PreferredImageIndex();
byte[] imageBytes = icoData.GetImage(preferredIndex);
// Convert into Bitmap and display in PictureBox
Bitmap iconBitmap = new Bitmap(new MemoryStream(imageBytes));
_pictureBox.Image = iconBitmap;
Here you would also have the option of accessing all images of the icon. GitHub Source
Upvotes: 1
Reputation: 59
This question might be old but here's my answer. Here's a full code snippet I used in extracting full 256 x 256 icons from any exe file.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace IconUtils
{
internal static class ExtractIcon
{
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal delegate bool ENUMRESNAMEPROC(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LockResource(IntPtr hResData);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
public static extern bool EnumResourceNames(IntPtr hModule, IntPtr lpszType, ENUMRESNAMEPROC lpEnumFunc, IntPtr lParam);
private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
private readonly static IntPtr RT_ICON = (IntPtr)3;
private readonly static IntPtr RT_GROUP_ICON = (IntPtr)14;
public static Icon ExtractIconFromExecutable(string path)
{
IntPtr hModule = LoadLibraryEx(path, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
var tmpData = new List<byte[]>();
ENUMRESNAMEPROC callback = (h, t, name, l) =>
{
var dir = GetDataFromResource(hModule, RT_GROUP_ICON, name);
// Calculate the size of an entire .icon file.
int count = BitConverter.ToUInt16(dir, 4); // GRPICONDIR.idCount
int len = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
for (int i = 0; i < count; ++i)
len += BitConverter.ToInt32(dir, 6 + 14 * i + 8); // GRPICONDIRENTRY.dwBytesInRes
using (var dst = new BinaryWriter(new MemoryStream(len)))
{
// Copy GRPICONDIR to ICONDIR.
dst.Write(dir, 0, 6);
int picOffset = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
for (int i = 0; i < count; ++i)
{
// Load the picture.
ushort id = BitConverter.ToUInt16(dir, 6 + 14 * i + 12); // GRPICONDIRENTRY.nID
var pic = GetDataFromResource(hModule, RT_ICON, (IntPtr)id);
// Copy GRPICONDIRENTRY to ICONDIRENTRY.
dst.Seek(6 + 16 * i, 0);
dst.Write(dir, 6 + 14 * i, 8); // First 8bytes are identical.
dst.Write(pic.Length); // ICONDIRENTRY.dwBytesInRes
dst.Write(picOffset); // ICONDIRENTRY.dwImageOffset
// Copy a picture.
dst.Seek(picOffset, 0);
dst.Write(pic, 0, pic.Length);
picOffset += pic.Length;
}
tmpData.Add(((MemoryStream)dst.BaseStream).ToArray());
}
return true;
};
EnumResourceNames(hModule, RT_GROUP_ICON, callback, IntPtr.Zero);
byte[][] iconData = tmpData.ToArray();
using (var ms = new MemoryStream(iconData[0]))
{
return new Icon(ms);
}
}
private static byte[] GetDataFromResource(IntPtr hModule, IntPtr type, IntPtr name)
{
// Load the binary data from the specified resource.
IntPtr hResInfo = FindResource(hModule, name, type);
IntPtr hResData = LoadResource(hModule, hResInfo);
IntPtr pResData = LockResource(hResData);
uint size = SizeofResource(hModule, hResInfo);
byte[] buf = new byte[size];
Marshal.Copy(pResData, buf, 0, buf.Length);
return buf;
}
}
}
Usage:
Icon ExeIcon = IconUtils.ExtractIcon.ExtractIconFromExecutable(@"C:\Windows\explorer.exe");
Source: https://www.codeproject.com/Articles/26824/Extract-icons-from-EXE-or-DLL-files
Upvotes: 0
Reputation: 244732
The code is surprisingly simple if you know where to look. Start with the Icon
class, since that's fundamentally what you're after here.
If you browse its methods, you'll come across a very interesting looking ExtractAssociatedIcon
. That accepts a single string parameter that specifies the path to a file containing an icon, such as an executable file.
So that gives you an Icon
object, now you just need to display it in a PictureBox. You don't have to convert it to a PNG or JPEG, a bitmap works fine. And there's a built-in member function for that: ToBitmap
.
Assigning the new bitmap to the PictureBox.Image
property is all you need to do to display it.
Upvotes: 10