您的位置:首页 > 其它

[.NET源码] 抽取exe和dll程序图标

2015-12-29 17:29 381 查看
从文件中抽取图标,我们可以选择使用ExtractIcon()或ExtractIconEx(),以及ExtractAssociatedIcon(),LoadImage()和SHGetFileInfo()。

下面我们比较和对照一下这些函数的能力:

函数

描述

ExtractIcon()

从一个文件中抽取指定索引位置的图标,索引从0开始。这个函数总是返回大图标(32x32)。

ExtractIconEx()

与ExtractIcon()相同,但是可以抽取大图标(32x32)和小图标(16x16)。

ExtractAssociatedIcon()

返回与给定文件或路径关联的大图标(32x32)。

SHGetFileInfo()

返回给定文件,路经或PIDL的大/小图标,也可以应用于某些图形效果。

LoadImage()

从给定文件中抽取期望分辨率的图标,这时唯一能取得48X48图标的方法。

LoadIcon()http://www.kmnk03.com/hxpfk/xmz/409.html

从给定可执行文件的资源中抽取图标,源文件由实例标识,不是由文件名标识,图标由ID标识不是由索引标识。

以上函数都提供了抽取程序图标的功能,但哪种方法最好呢?

1、如果我们只抽取大图标,也就是32x32的图标,我们推荐使用ExtractIcon()函数。

2、如果我们同时需要抽取大图标和小图标,绝对推荐使用ExtractIconEx()函数。

3、如果我们需要抽取48x48这样的超大图标,那么只能使用LoadImage()函数。

4、如果我们想获取Shell所关联的文件对象(驱动器,文件夹,打印机,普通文件等)的图标时,使用SHGetFileInfo()函数。

以下我们使用ExtractIconEx()函数详细讲解抽取图标的过程。

函数原型:UINT ExtractIcohEx(

LPCTSTR lpszFile,

int nIconIndex,

HICON FAR *phIconLarge,

HICON FAR *phIconSmall,

UINT nIcons);

参数:http://www.kmnk03.com/hxpfk/xmz/410.html

lpszFile:定义可获取图标的可执行文件,DLL,或者图标文件的名字的空结束字符串指针。

nIconIndex:指定抽取第一个图标基于零的变址;例如,如果该值是零;函数在限定的文件中抽取第一图标; 如该值是-1且phIconLarge和phIconSmall参数均为NULL,函数返回限定文件中图标的总数; 如果文件是可执行文件或DLL;返回值是RT_GROUP_ICON资源的数目;如果文件是一个ICO文件,返回值是1;Windows95,WindowsNT4.0,和更高版本中,如果值为负数且phIconLarge和phIconSmall均不为NULL,函数从获取图标开始,该图标的资源标识符等于nIconIndex绝对值。例如,使用-3来获取资源标识符为3的图标。

phIconLarge:指向图标句柄数组的指针,它可接收从文件获取的大图标的句柄。如果该参数是NULL没有从文件抽取大图标。

phIconSmall:指向图标句柄数组的指针,它可接收从文件获取的小图标的句柄。如果该参数是NULL,没有从文件抽取小图标。

nIcons:指定要从文件中抽取图标的数目。

返回值:如果nIconIndex参数是-1,PhIconLarge和PhIconSmall参数是NULL,返回值是包含在指定文件中的图标数目;否则,返回值是成功地从文件中获取图标的数目。

备注:必须调用DestroyIcon函数来清除由ExtractIconEx函数返回的图标。为恢复大小图标尺寸,可使用SM_CXICON,SM_CYICON,SM_CXSMICON,SM_CYSMICON标记来调用GetSystemMetrics函数。

[System.Runtime.InteropServices.DllImport("shell32.dll")]

private static extern int ExtractIconEx(string lpszFile, int niconIndex, IntPtr []phiconLarge,IntPtr []phiconSmall, int nIcons);http://www.kmnk03.com/hxpfk/xmz/411.html

private IntPtr[] largeIcons, smallIcons ; //存放大/小图标的指针数组

private string appPath = @"D:\Program Files\Tencent\QQ\Bin\QQ.exe";

//第一步:获取程序中的图标数

int IconCount = ExtractIconEx(appPath, -1, null,null, 0);

//第二步:创建存放大/小图标的空间

largeIcons = new IntPtr[IconCount];

smallIcons = new IntPtr[IconCount];

//第三步:抽取所有的大小图标保存到largeIcons和smallIcons中

ExtractIconEx(appPath, 0, largeIcons,smallIcons, IconCount);

//第四步:显示抽取的图标(推荐使用imageList和listview搭配显示)

for (int i = 0; i < IconCount; i++)

{http://www.kmnk03.com/hxpfk/xmz/412.html

this.imageList1.Images.Add(Icon.FromHandle(largeIcons[i])); //图标添加进imageList中

ListViewItem lvi = new ListViewItem();

lvi.ImageIndex = i; //listview子项图标索引项

this.listview1.Items.Add(lvi);

}

//第五步:保存图标

for (int i = 0; i < this.listview1.Items.Count; i++)

{http://www.kmnk03.com/hxpfk/xmz/413.html

System.IO.FileStream fs = new System.IO.FileStream(Application.StartupPath +"\\newIcon.png", System.IO.FileMode.Create);

this.imageList1.Images[this.listview1.Items[i].ImageIndex].Save(fs, System.Drawing.Imaging.ImageFormat.Png);

fs.Close();

}

复制代码

[StructLayout(LayoutKind.Sequential)]

public struct SHFILEINFO

{

public IntPtr hIcon;

public IntPtr iIcon;

public uint dwAttributes;http://www.kmnk01.com/hxpfk/2015/py_1229/381.html

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

public string szDisplayName;

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

public string szTypeName;

}

/// <summary>

/// 返回系统设置的图标

/// </summary>

/// <param name="pszPath">文件路径 如果为"" 返回文件夹的</param>

/// <param name="dwFileAttributes">0</param>

/// <param name="psfi">结构体</param>

/// <param name="cbSizeFileInfo">结构体大小</param>

/// <param name="uFlags">枚举类型</param>

/// <returns>-1失败</returns>

[DllImport("shell32.dll")]

public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
http://www.kmnk01.com/hxpfk/2015/py_1229/382.html
public enum SHGFI

{

SHGFI_ICON = 0x100,

SHGFI_LARGEICON = 0x0,

SHGFI_USEFILEATTRIBUTES = 0x10

}

/// <summary>

/// 获取文件图标 zgke@sina.com qq:116149

/// </summary>

/// <param name="p_Path">文件全路径</param>

/// <returns>图标</returns>

public static Icon GetFileIcon(string p_Path)

{http://www.kmnk01.com/hxpfk/2015/py_1229/383.html

SHFILEINFO _SHFILEINFO = new SHFILEINFO();

IntPtr _IconIntPtr = SHGetFileInfo(p_Path, 0, ref _SHFILEINFO, (uint)Marshal.SizeOf(_SHFILEINFO), (uint)(SHGFI.SHGFI_ICON | SHGFI.SHGFI_LARGEICON | SHGFI.SHGFI_USEFILEATTRIBUTES));

if (_IconIntPtr.Equals(IntPtr.Zero)) return null;

Icon _Icon = System.Drawing.Icon.FromHandle(_SHFILEINFO.hIcon);

return _Icon;

}

/// <summary>

/// 获取文件夹图标 zgke@sina.com qq:116149

/// </summary>

/// <returns>图标</returns>

public static Icon GetDirectoryIcon()

{

SHFILEINFO _SHFILEINFO = new SHFILEINFO();

IntPtr _IconIntPtr = SHGetFileInfo(@"", 0, ref _SHFILEINFO, (uint)Marshal.SizeOf(_SHFILEINFO), (uint)(SHGFI.SHGFI_ICON | SHGFI.SHGFI_LARGEICON));

if (_IconIntPtr.Equals(IntPtr.Zero)) return null;

Icon _Icon = System.Drawing.Icon.FromHandle(_SHFILEINFO.hIcon);

return _Icon;

}

复制代码

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;

using System.IO;
http://www.kmnk01.com/hxpfk/2015/py_1229/384.html
namespace WindowsApplication1

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

[StructLayout(LayoutKind.Sequential)]

public struct SHFILEINFO

{

public IntPtr hIcon;

public IntPtr iIcon;

public uint dwAttributes;

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

public string szDisplayName;

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

public string szTypeName;

};

class Win32

{

public const uint SHGFI_ICON = 0x100;

public const uint SHGFI_LARGEICON = 0x0; // 'Large icon

public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

[DllImport("shell32.dll")]

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

[DllImport("shell32.dll")]

public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);

}

private void button1_Click(object sender, EventArgs e)

{

openFileDialog1.ShowDialog();

SHFILEINFO shinfo = new SHFILEINFO();

Win32.SHGetFileInfo(openFileDialog1.FileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);http://www.kmnk01.com/hxpfk/2015/py_1229/385.html

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

FileStream fileStream = new FileStream("E:\\1.ico",FileMode.Create);

myIcon.Save(fileStream);

fileStream.Close();

}

}

}

复制代码

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

using System.Drawing;

using Microsoft.Win32;

namespace ifmdp.DeviceManager

{

class SystemIcon

{

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

public struct SHFILEINFO

{

public IntPtr hIcon;

public int iIcon;

public uint dwAttributes;

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

public string szDisplayName;

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

public string szTypeName;

}

[DllImport("Shell32.dll", EntryPoint = "SHGetFileInfo", SetLastError = true, CharSet = CharSet.Auto)]

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

[DllImport("User32.dll", EntryPoint = "DestroyIcon")]

public static extern int DestroyIcon(IntPtr hIcon);

#region API 参数的常量定义

public enum FileInfoFlags : uint

{

SHGFI_ICON = 0x000000100, // get icon

SHGFI_DISPLAYNAME = 0x000000200, // get display name

SHGFI_TYPENAME = 0x000000400, // get type name

SHGFI_ATTRIBUTES = 0x000000800, // get attributes

SHGFI_ICONLOCATION = 0x000001000, // get icon location

SHGFI_EXETYPE = 0x000002000, // return exe type

SHGFI_SYSICONINDEX = 0x000004000, // get system icon index

SHGFI_LINKOVERLAY = 0x000008000, // put a link overlay on icon

SHGFI_SELECTED = 0x000010000, // show icon in selected state

SHGFI_ATTR_SPECIFIED = 0x000020000, // get only specified attributes

SHGFI_LARGEICON = 0x000000000, // get large icon

SHGFI_SMALLICON = 0x000000001, // get small icon

SHGFI_OPENICON = 0x000000002, // get open icon

SHGFI_SHELLICONSIZE = 0x000000004, // get shell size icon

SHGFI_PIDL = 0x000000008, // pszPath is a pidl

SHGFI_USEFILEATTRIBUTES = 0x000000010, // use passed dwFileAttribute

SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays

SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay

}

public enum FileAttributeFlags : uint

{

FILE_ATTRIBUTE_READONLY = 0x00000001,

FILE_ATTRIBUTE_HIDDEN = 0x00000002,

FILE_ATTRIBUTE_SYSTEM = 0x00000004,

FILE_ATTRIBUTE_DIRECTORY = 0x00000010,

FILE_ATTRIBUTE_ARCHIVE = 0x00000020,

FILE_ATTRIBUTE_DEVICE = 0x00000040,

FILE_ATTRIBUTE_NORMAL = 0x00000080,

FILE_ATTRIBUTE_TEMPORARY = 0x00000100,

FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,

FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,

FILE_ATTRIBUTE_COMPRESSED = 0x00000800,

FILE_ATTRIBUTE_OFFLINE = 0x00001000,

FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,

FILE_ATTRIBUTE_ENCRYPTED = 0x00004000

}

#endregion

/// <summary>

/// 获取文件类型的关联图标

/// </summary>

/// <param name="fileName">文件类型的扩展名或文件的绝对路径</param>

/// <param name="isLargeIcon">是否返回大图标</param>

/// <returns>获取到的图标</returns>

public static Icon GetIcon(string fileName, bool isLargeIcon)

{

SHFILEINFO shfi = new SHFILEINFO();

IntPtr hI;

if (isLargeIcon)

hI = SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), (uint)FileInfoFlags.SHGFI_ICON | (uint)FileInfoFlags.SHGFI_USEFILEATTRIBUTES | (uint)FileInfoFlags.SHGFI_LARGEICON);

else

hI = SHGetFileInfo(fileName, 0, ref shfi, (uint)Marshal.SizeOf(shfi), (uint)FileInfoFlags.SHGFI_ICON | (uint)FileInfoFlags.SHGFI_USEFILEATTRIBUTES | (uint)FileInfoFlags.SHGFI_SMALLICON);

Icon icon = Icon.FromHandle(shfi.hIcon).Clone() as Icon;

DestroyIcon(shfi.hIcon); //释放资源

return icon;

}

/// <summary>

/// 获取文件夹图标

/// </summary>

/// <returns>图标</returns>

public static Icon GetDirectoryIcon(bool isLargeIcon)

{

SHFILEINFO _SHFILEINFO = new SHFILEINFO();

IntPtr _IconIntPtr;

if (isLargeIcon)

{

_IconIntPtr = SHGetFileInfo(@"", 0, ref _SHFILEINFO, (uint)Marshal.SizeOf(_SHFILEINFO), ((uint)FileInfoFlags.SHGFI_ICON | (uint)FileInfoFlags.SHGFI_LARGEICON));

}

else

{

_IconIntPtr = SHGetFileInfo(@"", 0, ref _SHFILEINFO, (uint)Marshal.SizeOf(_SHFILEINFO), ((uint)FileInfoFlags.SHGFI_ICON | (uint)FileInfoFlags.SHGFI_SMALLICON));

}

if (_IconIntPtr.Equals(IntPtr.Zero)) return null;

Icon _Icon = System.Drawing.Icon.FromHandle(_SHFILEINFO.hIcon);

return _Icon;

}

}

}

复制代码

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using System.IO;

using System.Runtime.InteropServices;

using Microsoft.Win32;

namespace CExplorer

{

public static class GetSystemIcon

{

/// <summary>

/// 依据文件名读取图标,若指定文件不存在,则返回空值。

/// </summary>

/// <param name="fileName">文件路径</param>

/// <param name="isLarge">是否返回大图标</param>

/// <returns></returns>

public static Icon GetIconByFileName(string fileName, bool isLarge = true)

{

int[] phiconLarge = new int[1];

int[] phiconSmall = new int[1];

//文件名 图标索引

Win32.ExtractIconEx(fileName, 0, phiconLarge, phiconSmall, 1);

IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);

return Icon.FromHandle(IconHnd);

}

/// <summary>

/// 根据文件扩展名(如:.*),返回与之关联的图标。

/// 若不以"."开头则返回文件夹的图标。

/// </summary>

/// <param name="fileType">文件扩展名</param>

/// <param name="isLarge">是否返回大图标</param>

/// <returns></returns>

public static Icon GetIconByFileType(string fileType, bool isLarge)

{

if (fileType == null || fileType.Equals(string.Empty)) return null;

RegistryKey regVersion = null;

string regFileType = null;

string regIconString = null;

string systemDirectory = Environment.SystemDirectory + "\\";

if (fileType[0] == '.')

{

//读系统注册表中文件类型信息

regVersion = Registry.ClassesRoot.OpenSubKey(fileType, true);

if (regVersion != null)

{

regFileType = regVersion.GetValue("") as string;

regVersion.Close();

regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"\DefaultIcon", true);

if (regVersion != null)

{

regIconString = regVersion.GetValue("") as string;

regVersion.Close();

}

}

if (regIconString == null)

{

//没有读取到文件类型注册信息,指定为未知文件类型的图标

regIconString = systemDirectory + "shell32.dll,0";

}

}

else

{

//直接指定为文件夹图标

regIconString = systemDirectory + "shell32.dll,3";

}

string[] fileIcon = regIconString.Split(new char[] { ',' });

if (fileIcon.Length != 2)

{

//系统注册表中注册的标图不能直接提取,则返回可执行文件的通用图标

fileIcon = new string[] { systemDirectory + "shell32.dll", "2" };

}

Icon resultIcon = null;

try

{

//调用API方法读取图标

int[] phiconLarge = new int[1];

int[] phiconSmall = new int[1];

uint count = Win32.ExtractIconEx(fileIcon[0], Int32.Parse(fileIcon[1]), phiconLarge, phiconSmall, 1);

IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);

resultIcon = Icon.FromHandle(IconHnd);

}

catch { }

return resultIcon;

}

}

/// <summary>

/// 定义调用的API方法

/// </summary>

class Win32

{

[DllImport("shell32.dll")]

public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);

}

}

kmnk01.com

kmnk03.com

www.kmnk01.com

www.kmnk03.com

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: