C# 抽取exe和dll程序图标

来源:互联网 发布:牛丁手表怎么样知乎 编辑:程序博客网 时间:2024/05/19 16:36

http://blog.csdn.net/czw2010/article/details/7900096

从文件中抽取图标,我们可以选择使用ExtractIcon()或ExtractIconEx(),以及ExtractAssociatedIcon(),LoadImage()和SHGetFileInfo()。

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

函数

描述

ExtractIcon()

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

ExtractIconEx()

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

ExtractAssociatedIcon()

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

SHGetFileInfo()

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

LoadImage()

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

LoadIcon()

从给定可执行文件的资源中抽取图标,源文件由实例标识,不是由文件名标识,图标由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);

参数:

      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函数。

源码:

[csharp] view plaincopyprint?
  1.   [System.Runtime.InteropServices.DllImport("shell32.dll")] 
  2.       private staticextern int ExtractIconEx(string lpszFile,int niconIndex, IntPtr []phiconLarge,IntPtr []phiconSmall,int nIcons); 
  3.  
  4.        private IntPtr[] largeIcons, smallIcons ; //存放大/小图标的指针数组 
  5.  
  6.        private string appPath = @"D:\Program Files\Tencent\QQ\Bin\QQ.exe"
  7.  
  8.       //第一步:获取程序中的图标数 
  9.       
  10.       int IconCount = ExtractIconEx(appPath, -1,null,null, 0);  
  11.     
  12.      //第二步:创建存放大/小图标的空间 
  13.  
  14.       largeIcons = new IntPtr[IconCount]; 
  15.      
  16.       smallIcons = new IntPtr[IconCount]; 
  17.  
  18.      //第三步:抽取所有的大小图标保存到largeIcons和smallIcons中 
  19.       
  20.       ExtractIconEx(appPath, 0, largeIcons,smallIcons, IconCount); 
  21.      
  22.      //第四步:显示抽取的图标(推荐使用imageList和listview搭配显示) 
  23.  
  24.       for (int i = 0; i < IconCount; i++) 
  25.       { 
  26.             this.imageList1.Images.Add(Icon.FromHandle(largeIcons[i]));//图标添加进imageList中 
  27.  
  28.             ListViewItem lvi = new ListViewItem(); 
  29.  
  30.             lvi.ImageIndex = i;  //listview子项图标索引项 
  31.  
  32.             this.listview1.Items.Add(lvi); 
  33.       } 
  34.  
  35.       //第五步:保存图标 
  36.        
  37.        for (int i = 0; i <this.listview1.Items.Count; i++) 
  38.        { 
  39.             System.IO.FileStream fs = new System.IO.FileStream(Application.StartupPath +"\\newIcon.png", System.IO.FileMode.Create); 
  40.  
  41.             this.imageList1.Images[this.listview1.Items[i].ImageIndex].Save(fs, System.Drawing.Imaging.ImageFormat.Png); 
  42.  
  43.             fs.Close(); 
  44.        }   

注意:

1、如果抽取的图标显示失真,把imageList1的属性ColorDepth值改为Depth32Bit即可解决该问题。

2、我们保存为ico格式的图标将会严重失真,系统提供的save其实只能保存为png格式,如果确实需要保存为ico格式的话,需要自己去找个开源的代码写入。

程序完成:

原创粉丝点击