FileIcon.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. using System.Runtime.InteropServices;
  8. using System.Windows.Media.Imaging;
  9. namespace GeekDesk.Util
  10. {
  11. public class FileIcon
  12. {
  13. static List<string> blurExtsList;
  14. static List<int[]> pixelList;
  15. static FileIcon() {
  16. blurExtsList = new List<string>
  17. {
  18. ".exe",
  19. ".cer",
  20. ".lnk",
  21. ".chm"
  22. };
  23. pixelList = new List<int[]>
  24. {
  25. new int[]{ 256 / 4, 256 / 4 },
  26. new int[]{ 256 / 2, 256 / 4 },
  27. new int[]{ 256 / 4 * 3, 256 / 4 },
  28. new int[]{ 256 / 4, 256 / 2 },
  29. new int[]{ 256 / 4, 256 / 4 * 3 },
  30. new int[]{ 256 / 4 * 3, 256 / 2 },
  31. new int[]{ 256 / 4 * 3, 256 / 4 * 3 },
  32. new int[]{ 256 / 2, 256 / 4 * 3 },
  33. };
  34. }
  35. [DllImport("User32.dll")]
  36. public static extern int PrivateExtractIcons(
  37. string lpszFile, //文件名可以是exe,dll,ico,cur,ani,bmp
  38. int nIconIndex, //从第几个图标开始获取
  39. int cxIcon, //获取图标的尺寸x
  40. int cyIcon, //获取图标的尺寸y
  41. IntPtr[] phicon, //获取到的图标指针数组
  42. int[] piconid, //图标对应的资源编号
  43. int nIcons, //指定获取的图标数量,仅当文件类型为.exe 和 .dll时候可用
  44. int flags //标志,默认0就可以,具体可以看LoadImage函数
  45. );
  46. public static BitmapImage GetBitmapImage(string filePath)
  47. {
  48. Icon ico;
  49. //选中文件中的图标总数
  50. var iconTotalCount = PrivateExtractIcons(filePath, 0, 0, 0, null, null, 0, 0);
  51. //用于接收获取到的图标指针
  52. IntPtr[] hIcons = new IntPtr[iconTotalCount];
  53. //对应的图标id
  54. int[] ids = new int[iconTotalCount];
  55. //成功获取到的图标个数
  56. var successCount = PrivateExtractIcons(filePath, 0, 256, 256, hIcons, ids, iconTotalCount, 0);
  57. string ext = Path.GetExtension(filePath).ToLower();
  58. IntPtr ip = IntPtr.Zero;
  59. if (successCount > 0)
  60. {
  61. ip = hIcons[0];
  62. ico = Icon.FromHandle(ip);
  63. }
  64. else if (blurExtsList.Contains(ext))
  65. {
  66. ico = Icon.ExtractAssociatedIcon(filePath);
  67. }
  68. else
  69. {
  70. ip = GetJumboIcon(GetIconIndex(filePath));
  71. ico = Icon.FromHandle(ip);
  72. if (CheckIsSmallIco(ico.ToBitmap()))
  73. {
  74. ico = Icon.ExtractAssociatedIcon(filePath);
  75. }
  76. }
  77. Bitmap bmp = ico.ToBitmap();
  78. MemoryStream strm = new MemoryStream();
  79. ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/png");
  80. Encoder myEncoder = Encoder.Quality;
  81. EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 75L);
  82. EncoderParameters myEncoderParameters = new EncoderParameters(1);
  83. myEncoderParameters.Param[0] = myEncoderParameter;
  84. bmp.Save(strm, myImageCodecInfo, myEncoderParameters);
  85. BitmapImage bmpImage = new BitmapImage();
  86. bmpImage.BeginInit();
  87. strm.Seek(0, SeekOrigin.Begin);
  88. bmpImage.StreamSource = strm;
  89. bmpImage.EndInit();
  90. if (ip != IntPtr.Zero)
  91. {
  92. Shell32.DestroyIcon(ip);
  93. }
  94. DeleteObject(bmp.GetHbitmap());
  95. return bmpImage.Clone();
  96. }
  97. private static ImageCodecInfo GetEncoderInfo(String mimeType)
  98. {
  99. int j;
  100. ImageCodecInfo[] encoders;
  101. encoders = ImageCodecInfo.GetImageEncoders();
  102. for (j = 0; j < encoders.Length; ++j)
  103. {
  104. if (encoders[j].MimeType == mimeType)
  105. return encoders[j];
  106. }
  107. return null;
  108. }
  109. private static bool CheckIsSmallIco(Bitmap bm)
  110. {
  111. Color color;
  112. int count = 0;
  113. foreach (int[] arr in pixelList)
  114. {
  115. color = bm.GetPixel(arr[0], arr[1]);
  116. if (color.A == 0)
  117. {
  118. count++;
  119. }
  120. }
  121. DeleteObject(bm.GetHbitmap());
  122. if (count >= 6)
  123. {
  124. return true;
  125. }
  126. return false;
  127. }
  128. [System.Runtime.InteropServices.DllImport("gdi32.dll")]
  129. public static extern bool DeleteObject(IntPtr onj);
  130. public static int GetIconIndex(string pszFile)
  131. {
  132. SHFILEINFO sfi = new SHFILEINFO();
  133. Shell32.SHGetFileInfo(pszFile
  134. , 0
  135. , ref sfi
  136. , (uint)System.Runtime.InteropServices.Marshal.SizeOf(sfi)
  137. , (uint)(SHGFI.SysIconIndex | SHGFI.LargeIcon | SHGFI.UseFileAttributes));
  138. return sfi.iIcon;
  139. }
  140. // 256*256
  141. public static IntPtr GetJumboIcon(int iImage)
  142. {
  143. IImageList spiml = null;
  144. Guid guil = new Guid(IID_IImageList);//or IID_IImageList
  145. Shell32.SHGetImageList(Shell32.SHIL_JUMBO, ref guil, ref spiml);
  146. IntPtr hIcon = IntPtr.Zero;
  147. spiml.GetIcon(iImage, Shell32.ILD_TRANSPARENT | Shell32.ILD_IMAGE, ref hIcon);
  148. return hIcon;
  149. }
  150. const string IID_IImageList = "46EB5926-582E-4017-9FDF-E8998DAA0950";
  151. const string IID_IImageList2 = "192B9D83-50FC-457B-90A0-2B82A8B5DAE1";
  152. public static class Shell32
  153. {
  154. public const int SHIL_LARGE = 0x0;
  155. public const int SHIL_SMALL = 0x1;
  156. public const int SHIL_EXTRALARGE = 0x2;
  157. public const int SHIL_SYSSMALL = 0x3;
  158. public const int SHIL_JUMBO = 0x4;
  159. public const int SHIL_LAST = 0x4;
  160. public const int ILD_TRANSPARENT = 0x00000001;
  161. public const int ILD_IMAGE = 0x00000020;
  162. [DllImport("shell32.dll", EntryPoint = "#727")]
  163. public extern static int SHGetImageList(int iImageList, ref Guid riid, ref IImageList ppv);
  164. [DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
  165. public static unsafe extern int DestroyIcon(IntPtr hIcon);
  166. [DllImport("shell32.dll")]
  167. public static extern uint SHGetIDListFromObject([MarshalAs(UnmanagedType.IUnknown)] object iUnknown, out IntPtr ppidl);
  168. [DllImport("Shell32.dll")]
  169. public static extern IntPtr SHGetFileInfo(
  170. string pszPath,
  171. uint dwFileAttributes,
  172. ref SHFILEINFO psfi,
  173. uint cbFileInfo,
  174. uint uFlags
  175. );
  176. }
  177. [Flags]
  178. enum SHGFI : uint
  179. {
  180. /// <summary>get icon</summary>
  181. Icon = 0x000000100,
  182. /// <summary>get display name</summary>
  183. DisplayName = 0x000000200,
  184. /// <summary>get type name</summary>
  185. TypeName = 0x000000400,
  186. /// <summary>get attributes</summary>
  187. Attributes = 0x000000800,
  188. /// <summary>get icon location</summary>
  189. IconLocation = 0x000001000,
  190. /// <summary>return exe type</summary>
  191. ExeType = 0x000002000,
  192. /// <summary>get system icon index</summary>
  193. SysIconIndex = 0x000004000,
  194. /// <summary>put a link overlay on icon</summary>
  195. LinkOverlay = 0x000008000,
  196. /// <summary>show icon in selected state</summary>
  197. Selected = 0x000010000,
  198. /// <summary>get only specified attributes</summary>
  199. Attr_Specified = 0x000020000,
  200. /// <summary>get large icon</summary>
  201. LargeIcon = 0x000000000,
  202. /// <summary>get small icon</summary>
  203. SmallIcon = 0x000000001,
  204. /// <summary>get open icon</summary>
  205. OpenIcon = 0x000000002,
  206. /// <summary>get shell size icon</summary>
  207. ShellIconSize = 0x000000004,
  208. /// <summary>pszPath is a pidl</summary>
  209. PIDL = 0x000000008,
  210. /// <summary>use passed dwFileAttribute</summary>
  211. UseFileAttributes = 0x000000010,
  212. /// <summary>apply the appropriate overlays</summary>
  213. AddOverlays = 0x000000020,
  214. /// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
  215. OverlayIndex = 0x000000040,
  216. }
  217. [StructLayout(LayoutKind.Sequential)]
  218. public struct SHFILEINFO
  219. {
  220. public const int NAMESIZE = 80;
  221. public IntPtr hIcon;
  222. public int iIcon;
  223. public uint dwAttributes;
  224. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  225. public string szDisplayName;
  226. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
  227. public string szTypeName;
  228. };
  229. [StructLayout(LayoutKind.Sequential)]
  230. public struct RECT
  231. {
  232. public int left, top, right, bottom;
  233. }
  234. [StructLayout(LayoutKind.Sequential)]
  235. public struct POINT
  236. {
  237. int x;
  238. int y;
  239. }
  240. [StructLayout(LayoutKind.Sequential)]
  241. public struct IMAGELISTDRAWPARAMS
  242. {
  243. public int cbSize;
  244. public IntPtr himl;
  245. public int i;
  246. public IntPtr hdcDst;
  247. public int x;
  248. public int y;
  249. public int cx;
  250. public int cy;
  251. public int xBitmap; // x offest from the upperleft of bitmap
  252. public int yBitmap; // y offset from the upperleft of bitmap
  253. public int rgbBk;
  254. public int rgbFg;
  255. public int fStyle;
  256. public int dwRop;
  257. public int fState;
  258. public int Frame;
  259. public int crEffect;
  260. }
  261. [StructLayout(LayoutKind.Sequential)]
  262. public struct IMAGEINFO
  263. {
  264. public IntPtr hbmImage;
  265. public IntPtr hbmMask;
  266. public int Unused1;
  267. public int Unused2;
  268. public RECT rcImage;
  269. }
  270. [ComImportAttribute()]
  271. [GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")]
  272. [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
  273. public interface IImageList
  274. {
  275. [PreserveSig]
  276. int Add(
  277. IntPtr hbmImage,
  278. IntPtr hbmMask,
  279. ref int pi);
  280. [PreserveSig]
  281. int ReplaceIcon(
  282. int i,
  283. IntPtr hicon,
  284. ref int pi);
  285. [PreserveSig]
  286. int SetOverlayImage(
  287. int iImage,
  288. int iOverlay);
  289. [PreserveSig]
  290. int Replace(
  291. int i,
  292. IntPtr hbmImage,
  293. IntPtr hbmMask);
  294. [PreserveSig]
  295. int AddMasked(
  296. IntPtr hbmImage,
  297. int crMask,
  298. ref int pi);
  299. [PreserveSig]
  300. int Draw(
  301. ref IMAGELISTDRAWPARAMS pimldp);
  302. [PreserveSig]
  303. int Remove(int i);
  304. [PreserveSig]
  305. int GetIcon(
  306. int i,
  307. int flags,
  308. ref IntPtr picon);
  309. [PreserveSig]
  310. int GetImageInfo(
  311. int i,
  312. ref IMAGEINFO pImageInfo);
  313. [PreserveSig]
  314. int Copy(
  315. int iDst,
  316. IImageList punkSrc,
  317. int iSrc,
  318. int uFlags);
  319. [PreserveSig]
  320. int Merge(
  321. int i1,
  322. IImageList punk2,
  323. int i2,
  324. int dx,
  325. int dy,
  326. ref Guid riid,
  327. ref IntPtr ppv);
  328. [PreserveSig]
  329. int Clone(
  330. ref Guid riid,
  331. ref IntPtr ppv);
  332. [PreserveSig]
  333. int GetImageRect(
  334. int i,
  335. ref RECT prc);
  336. [PreserveSig]
  337. int GetIconSize(
  338. ref int cx,
  339. ref int cy);
  340. [PreserveSig]
  341. int SetIconSize(
  342. int cx,
  343. int cy);
  344. [PreserveSig]
  345. int GetImageCount(ref int pi);
  346. [PreserveSig]
  347. int SetImageCount(
  348. int uNewCount);
  349. [PreserveSig]
  350. int SetBkColor(
  351. int clrBk,
  352. ref int pclr);
  353. [PreserveSig]
  354. int GetBkColor(
  355. ref int pclr);
  356. [PreserveSig]
  357. int BeginDrag(
  358. int iTrack,
  359. int dxHotspot,
  360. int dyHotspot);
  361. [PreserveSig]
  362. int EndDrag();
  363. [PreserveSig]
  364. int DragEnter(
  365. IntPtr hwndLock,
  366. int x,
  367. int y);
  368. [PreserveSig]
  369. int DragLeave(
  370. IntPtr hwndLock);
  371. [PreserveSig]
  372. int DragMove(
  373. int x,
  374. int y);
  375. [PreserveSig]
  376. int SetDragCursorImage(
  377. ref IImageList punk,
  378. int iDrag,
  379. int dxHotspot,
  380. int dyHotspot);
  381. [PreserveSig]
  382. int DragShowNolock(
  383. int fShow);
  384. [PreserveSig]
  385. int GetDragImage(
  386. ref POINT ppt,
  387. ref POINT pptHotspot,
  388. ref Guid riid,
  389. ref IntPtr ppv);
  390. [PreserveSig]
  391. int GetItemFlags(
  392. int i,
  393. ref int dwFlags);
  394. [PreserveSig]
  395. int GetOverlayImage(
  396. int iOverlay,
  397. ref int piIndex);
  398. };
  399. }
  400. }