FileIcon.cs 12 KB

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