FileIcon.cs 12 KB

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