Extracting Icons from Files

In this C# tutorial you will learn how to extract the graphic icon from a file by using a Shell32.dll API call to the unmanaged method SHGetFileInfo().

With this tutorial we’re touching the unmanaged code of Windows again since we’re going to use the SHGetFileInfo() API function. First let’s add the needed reference to InteropServices:

using System.Runtime.InteropServices;

A bunch of constants we will use in the call to SHGetFileInfo() to specify the size of the icon we wish to retrieve:

// Constants that we need in the function call

private const int SHGFI_ICON = 0x100;

private const int SHGFI_SMALLICON = 0x1;

private const int SHGFI_LARGEICON = 0x0;

The SHFILEINFO structure is very important as it will be our handle to various file information, among which is the graphic icon.

// This structure will contain information about the file

public struct SHFILEINFO

{

    // Handle to the icon representing the file

    public IntPtr hIcon;

    // Index of the icon within the image list

    public int iIcon;

    // Various attributes of the file

    public uint dwAttributes;

    // Path to the file

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

    public string szDisplayName;

    // File type

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]

    public string szTypeName;

};

The final preparation for the unmanaged code is to define the signature of SHGetFileInfo, which is located inside the popular Shell32.dll:

// The signature of SHGetFileInfo (located in Shell32.dll)

[DllImport("Shell32.dll")]

public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);

Now that we have everything prepared, it's time to make the call to the function and display the icon that we retrieved. The object that will be retrieved is an Icon type (System.Drawing.Icon) but we want to display it in a PictureBox so we'll convert the Icon to a Bitmap using the ToBitmap() method.

But first of all there are 3 controls you need to add to the form, a Button btnExtract that has "Extract Icon" for its Text property, picIconSmall which is a PictureBox and a picIconLarge which is also a PictureBox. That's because we will get two icons sizes. Now double click btnExtract in Visual Studio's Design view and you'll get to its Click event. Inside it is the rest of the code:
private void btnExtract_Click(object sender, EventArgs e)

{

    // Will store a handle to the small icon

    IntPtr hImgSmall;

    // Will store a handle to the large icon

    IntPtr hImgLarge;

 

    SHFILEINFO shinfo = new SHFILEINFO();

 

    // Open the file that we wish to extract the icon from

    if(openFile.ShowDialog() == DialogResult.OK)

    {

        // Store the file name

        string FileName = openFile.FileName;

        // Sore the icon in this myIcon object

        System.Drawing.Icon myIcon;

 

        // Get a handle to the small icon

        hImgSmall = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);

        // Get the small icon from the handle

        myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);

        // Display the small icon

        picIconSmall.Image = myIcon.ToBitmap();

 

        // Get a handle to the large icon

        hImgLarge = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON);

        // Get the large icon from the handle

        myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);

        // Display the large icon

        picIconLarge.Image = myIcon.ToBitmap();

 

    }

}

It’s pretty much self explanatory with all the comments, but if you have questions, you can always leave a comment. Here’s the Icon Extractor application in action:

Below is the full source code of the application. You can also download this in a Visual Studio 2005 solution using the link at the top of the tutorial.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

 

namespace ExtractIcon

{

    public partial class Form1 : Form

    {

        // Constants that we need in the function call

        private const int SHGFI_ICON = 0x100;

        private const int SHGFI_SMALLICON = 0x1;

        private const int SHGFI_LARGEICON = 0x0;

 

        // This structure will contain information about the file

        public struct SHFILEINFO

        {

            // Handle to the icon representing the file

            public IntPtr hIcon;

            // Index of the icon within the image list

            public int iIcon;

            // Various attributes of the file

            public uint dwAttributes;

            // Path to the file

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

            public string szDisplayName;

            // File type

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]

            public string szTypeName;

        };

 

        // The signature of SHGetFileInfo (located in Shell32.dll)

        [DllImport("Shell32.dll")]

        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);

 

        public Form1()

        {

            InitializeComponent();

        }

 

        private void btnExtract_Click(object sender, EventArgs e)

        {

            // Will store a handle to the small icon

            IntPtr hImgSmall;

            // Will store a handle to the large icon

            IntPtr hImgLarge;

 

            SHFILEINFO shinfo = new SHFILEINFO();

 

            // Open the file that we wish to extract the icon from

            if(openFile.ShowDialog() == DialogResult.OK)

            {

                // Store the file name

                string FileName = openFile.FileName;

                // Sore the icon in this myIcon object

                System.Drawing.Icon myIcon;

 

                // Get a handle to the small icon

                hImgSmall = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);

                // Get the small icon from the handle

                myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);

                // Display the small icon

                picIconSmall.Image = myIcon.ToBitmap();

 

                // Get a handle to the large icon

                hImgLarge = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON);

                // Get the large icon from the handle

                myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);

                // Display the large icon

                picIconLarge.Image = myIcon.ToBitmap();

 

            }

        }

    }

}
Nathan Pakovskie is an esteemed senior developer and educator in the tech community, best known for his contributions to Geekpedia.com. With a passion for coding and a knack for simplifying complex tech concepts, Nathan has authored several popular tutorials on C# programming, ranging from basic operations to advanced coding techniques. His articles, often characterized by clarity and precision, serve as invaluable resources for both novice and experienced programmers. Beyond his technical expertise, Nathan is an advocate for continuous learning and enjoys exploring emerging technologies in AI and software development. When he’s not coding or writing, Nathan engages in mentoring upcoming developers, emphasizing the importance of both technical skills and creative problem-solving in the ever-evolving world of technology. Specialties: C# Programming, Technical Writing, Software Development, AI Technologies, Educational Outreach

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top