[C#] Hướng dẫn lấy icon từ thuộc tính file shell32.dll trong windows
Bài viết hôm nay, mình sẽ hướng dẫn các bạn cách lấy các icon từ extension (phần mở rộng của file) trong lập trình C# . Nếu bạn nào viết ứng dụng load dữ liệu các file từ thư mục lên listbox hay listview . Thì lúc hiển thị thì sẽ xuất ...
Bài viết hôm nay, mình sẽ hướng dẫn các bạn cách lấy các icon từ extension (phần mở rộng của file) trong lập trình C#.
Nếu bạn nào viết ứng dụng load dữ liệu các file từ thư mục lên listbox hay listview.
Thì lúc hiển thị thì sẽ xuất hiện tên file, vậy nếu mình muốn hiển thị thêm icon tùy theo định dạng file nữa thì mình sẽ làm thế nào.
Demo ứng dụng dưới đây sẽ giúp bạn giải quyết vấn đề đó:
- Đầu tiên , các bạn tạo một class với tên sau: RegisteredFileType.cs
using System; using System.Collections.Generic; using System.Collections; using System.Text; using System.Runtime.InteropServices; using Microsoft.Win32; using System.Drawing; namespace FileTypeAndIcon { /// <summary> /// Structure that encapsulates basic information of icon embedded in a file. /// </summary> public struct EmbeddedIconInfo { public string FileName; public int IconIndex; } public class RegisteredFileType { #region APIs [DllImport("shell32.dll", EntryPoint = "ExtractIconA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] private static extern IntPtr ExtractIcon(int hInst, string lpszExeFileName, int nIconIndex); [DllImport("shell32.dll", CharSet = CharSet.Auto)] private static extern uint ExtractIconEx(string szFileName, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons); [DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)] private static unsafe extern int DestroyIcon(IntPtr hIcon); #endregion #region CORE METHODS /// <summary> /// Gets registered file types and their associated icon in the system. /// </summary> /// <returns>Returns a hash table which contains the file extension as keys, the icon file and param as values.</returns> public static Hashtable GetFileTypeAndIcon() { try { // Create a registry key object to represent the HKEY_CLASSES_ROOT registry section RegistryKey rkRoot = Registry.ClassesRoot; //Gets all sub keys' names. string[] keyNames = rkRoot.GetSubKeyNames(); Hashtable iconsInfo = new Hashtable(); //Find the file icon. foreach (string keyName in keyNames) { if (String.IsNullOrEmpty(keyName)) continue; int indexOfPoint = keyName.IndexOf("."); //If this key is not a file exttension(eg, .zip), skip it. if (indexOfPoint != 0) continue; RegistryKey rkFileType = rkRoot.OpenSubKey(keyName); if (rkFileType == null) continue; //Gets the default value of this key that contains the information of file type. object defaultValue = rkFileType.GetValue(""); if (defaultValue == null) continue; //Go to the key that specifies the default icon associates with this file type. string defaultIcon = defaultValue.ToString() + "\DefaultIcon"; RegistryKey rkFileIcon = rkRoot.OpenSubKey(defaultIcon); if (rkFileIcon != null) { //Get the file contains the icon and the index of the icon in that file. object value = rkFileIcon.GetValue(""); if (value != null) { //Clear all unecessary " sign in the string to avoid error. string fileParam = value.ToString().Replace(""", ""); iconsInfo.Add(keyName, fileParam); } rkFileIcon.Close(); } rkFileType.Close(); } rkRoot.Close(); return iconsInfo; } catch (Exception exc) { throw exc; } } /// <summary> /// Extract the icon from file. /// </summary> /// <param name="fileAndParam">The params string, /// such as ex: "C:\Program Files\NetMeeting\conf.exe,1".</param> /// <returns>This method always returns the large size of the icon (may be 32x32 px).</returns> public static Icon ExtractIconFromFile(string fileAndParam) { try { EmbeddedIconInfo embeddedIcon = getEmbeddedIconInfo(fileAndParam); //Gets the handle of the icon. IntPtr lIcon = ExtractIcon(0, embeddedIcon.FileName, embeddedIcon.IconIndex); //Gets the real icon. return Icon.FromHandle(lIcon); } catch (Exception exc) { throw exc; } } /// <summary> /// Extract the icon from file. /// </summary> /// <param name="fileAndParam">The params string, /// such as ex: "C:\Program Files\NetMeeting\conf.exe,1".</param> /// <param name="isLarge"> /// Determines the returned icon is a large (may be 32x32 px) /// or small icon (16x16 px).</param> public static Icon ExtractIconFromFile(string fileAndParam, bool isLarge) { unsafe { uint readIconCount = 0; IntPtr[] hDummy = new IntPtr[1] { IntPtr.Zero }; IntPtr[] hIconEx = new IntPtr[1] { IntPtr.Zero }; try { EmbeddedIconInfo embeddedIcon = getEmbeddedIconInfo(fileAndParam); if (isLarge) readIconCount = ExtractIconEx(embeddedIcon.FileName, 0, hIconEx, hDummy, 1); else readIconCount = ExtractIconEx(embeddedIcon.FileName, 0, hDummy, hIconEx, 1); if (readIconCount > 0 && hIconEx[0] != IntPtr.Zero) { // Get first icon. Icon extractedIcon = (Icon)Icon.FromHandle(hIconEx[0]).Clone(); return extractedIcon; } else // No icon read return null; } catch (Exception exc) { // Extract icon error. throw new ApplicationException("Could not extract icon", exc); } finally { // Release resources. foreach (IntPtr ptr in hIconEx) if (ptr != IntPtr.Zero) DestroyIcon(ptr); foreach (IntPtr ptr in hDummy) if (ptr != IntPtr.Zero) DestroyIcon(ptr); } } } #endregion #region UTILITY METHODS /// <summary> /// Parses the parameters string to the structure of EmbeddedIconInfo. /// </summary> /// <param name="fileAndParam">The params string, /// such as ex: "C:\Program Files\NetMeeting\conf.exe,1".</param> /// <returns></returns> protected static EmbeddedIconInfo getEmbeddedIconInfo(string fileAndParam) { EmbeddedIconInfo embeddedIcon = new EmbeddedIconInfo(); if (String.IsNullOrEmpty(fileAndParam)) return embeddedIcon; //Use to store the file contains icon. string fileName = String.Empty; //The index of the icon in the file. int iconIndex = 0; string iconIndexString = String.Empty; int commaIndex = fileAndParam.IndexOf(","); //if fileAndParam is some thing likes that: "C:\Program Files\NetMeeting\conf.exe,1". if (commaIndex > 0) { fileName = fileAndParam.Substring(0, commaIndex); iconIndexString = fileAndParam.Substring(commaIndex + 1); } else fileName = fileAndParam; if (!String.IsNullOrEmpty(iconIndexString)) { //Get the index of icon. iconIndex = int.Parse(iconIndexString); if (iconIndex < 0) iconIndex = 0; //To avoid the invalid index. } embeddedIcon.FileName = fileName; embeddedIcon.IconIndex = iconIndex; return embeddedIcon; } #endregion } }
Source code form main C#
using System; using System.Collections.Generic; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace FileTypeAndIcon { public partial class IconForm : Form { #region MEMBERS /// <summary> /// Used for containing file types and their icons information. /// </summary> private Hashtable iconsInfo; private ImageSize currentSize; public ImageSize CurrentImageSize { get { return currentSize; } set { this.currentSize = value; } } public enum ImageSize { /// <summary> /// View image in 16x16 px. /// </summary> Small, /// <summary> /// View image in 32x32 px. /// </summary> Large } #endregion #region CONSTRUCTORS public IconForm() { InitializeComponent(); } #endregion #region GUI EVENTS private void IconForm_Load(object sender, EventArgs e) { try { //Gets file type and icon info. this.iconsInfo = RegisteredFileType.GetFileTypeAndIcon(); this.currentSize = ImageSize.Large; //Loads file types to ListBox. foreach (object objString in this.iconsInfo.Keys) { this.lbxFileType.Items.Add(objString); } } catch (Exception exc) { MessageBox.Show(exc.Message); } } private void btnSearch_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(this.txtSearch.Text.Trim())) return; string searchName = String.Empty; if (!this.txtSearch.Text.Contains(".")) searchName = "." + this.txtSearch.Text; //Add a dot if the search text does not have it. else searchName = this.txtSearch.Text; //Searches in the collections of file types and icons. object objName = this.iconsInfo[searchName]; if (objName != null) { this.lbxFileType.SelectedItem = searchName; } } private void lbxFileType_SelectedIndexChanged(object sender, EventArgs e) { this.renderImage(); } private void txtSearch_TextChanged(object sender, EventArgs e) { if (string.IsNullOrEmpty(this.txtSearch.Text.Trim())) { this.btnSearch.Enabled = false; } else { this.btnSearch.Enabled = true; } } private void rbLarge_CheckedChanged(object sender, EventArgs e) { if (this.rbLarge.Checked) { this.currentSize = ImageSize.Large; this.renderImage(); } } private void rbSmall_CheckedChanged(object sender, EventArgs e) { if (this.rbSmall.Checked) { this.currentSize = ImageSize.Small; this.renderImage(); } } #endregion #region UTILITY METHODS /// <summary> /// Validates the input data and renders the image. /// </summary> private void renderImage() { try { if (this.lbxFileType.Items.Count <= 0 || this.lbxFileType.SelectedItem == null) return; string fileType = this.lbxFileType.SelectedItem.ToString(); this.showIcon(fileType); } catch (Exception exc) { MessageBox.Show(exc.Message); } } /// <summary> /// Shows the icon associates with a specific file type. /// </summary> /// <param name="fileType">The type of file (or file extension).</param> private void showIcon(string fileType) { try { string fileAndParam = (this.iconsInfo[fileType]).ToString(); if (String.IsNullOrEmpty(fileAndParam)) return; Icon icon = null; bool isLarge = true; if (currentSize == ImageSize.Small) isLarge = false; icon = RegisteredFileType.ExtractIconFromFile(fileAndParam, isLarge); //RegisteredFileType.ExtractIconFromFile(fileAndParam); //The icon cannot be zero. if (icon != null) { //Draw the icon to the picture box. this.pbIconView.Image = icon.ToBitmap(); } else //if the icon is invalid, show an error image. this.pbIconView.Image = this.pbIconView.ErrorImage; } catch (Exception exc) { throw exc; } } #endregion } }
HAVE FUN :)
DOWNLOAD SOURCE