FileIconUtils.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 Microsoft.Win32;
  8. namespace prBrowser
  9. {
  10. public static class FileIconUtils
  11. {
  12. public class IconNotFoundException : Exception
  13. {
  14. public IconNotFoundException(string fileName, int index)
  15. : base($"Icon with Id = {index} wasn't found in file {fileName}")
  16. {
  17. }
  18. }
  19. public class UnableToExtractIconsException : Exception
  20. {
  21. public UnableToExtractIconsException(string fileName, int firstIconIndex, int iconCount)
  22. : base(string.Format("Tryed to extract {2} icons starting from the one with id {1} from the \"{0}\" file but failed", fileName, firstIconIndex, iconCount))
  23. {
  24. }
  25. }
  26. private struct SHFILEINFO
  27. {
  28. public IntPtr hIcon;
  29. public IntPtr iIcon;
  30. public uint dwAttributes;
  31. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  32. public string szDisplayName;
  33. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
  34. public string szTypeName;
  35. }
  36. [Flags]
  37. private enum FileInfoFlags
  38. {
  39. SHGFI_ICON = 0x100,
  40. SHGFI_USEFILEATTRIBUTES = 0x10
  41. }
  42. public static MemoryStream GetFileIcon(string name, FileIconSize size)
  43. {
  44. Icon icon = IconFromExtension(name.GetAfter("."), size);
  45. using (icon)
  46. {
  47. using Bitmap bmp = icon.ToBitmap();
  48. MemoryStream ms = new MemoryStream();
  49. bmp.Save(ms, ImageFormat.Png);
  50. ms.Seek(0L, SeekOrigin.Begin);
  51. return ms;
  52. }
  53. }
  54. [DllImport("Shell32", CharSet = CharSet.Auto)]
  55. private static extern int ExtractIconEx([MarshalAs(UnmanagedType.LPTStr)] string lpszFile, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, int nIcons);
  56. [DllImport("Shell32", CharSet = CharSet.Auto)]
  57. private static extern IntPtr SHGetFileInfo(string pszPath, int dwFileAttributes, out SHFILEINFO psfi, int cbFileInfo, FileInfoFlags uFlags);
  58. public static void ExtractEx(string fileName, List<Icon> largeIcons, List<Icon> smallIcons, int firstIconIndex, int iconCount)
  59. {
  60. IntPtr[] smallIconsPtrs = null;
  61. IntPtr[] largeIconsPtrs = null;
  62. if (smallIcons != null)
  63. {
  64. smallIconsPtrs = new IntPtr[iconCount];
  65. }
  66. if (largeIcons != null)
  67. {
  68. largeIconsPtrs = new IntPtr[iconCount];
  69. }
  70. int apiResult = ExtractIconEx(fileName, firstIconIndex, largeIconsPtrs, smallIconsPtrs, iconCount);
  71. if (apiResult != iconCount)
  72. {
  73. throw new UnableToExtractIconsException(fileName, firstIconIndex, iconCount);
  74. }
  75. if (smallIcons != null)
  76. {
  77. smallIcons.Clear();
  78. IntPtr[] array = smallIconsPtrs;
  79. foreach (IntPtr actualIconPtr2 in array)
  80. {
  81. smallIcons.Add(Icon.FromHandle(actualIconPtr2));
  82. }
  83. }
  84. if (largeIcons != null)
  85. {
  86. largeIcons.Clear();
  87. IntPtr[] array2 = largeIconsPtrs;
  88. foreach (IntPtr actualIconPtr in array2)
  89. {
  90. largeIcons.Add(Icon.FromHandle(actualIconPtr));
  91. }
  92. }
  93. }
  94. public static List<Icon> ExtractEx(string fileName, FileIconSize size, int firstIconIndex, int iconCount)
  95. {
  96. List<Icon> iconList = new List<Icon>();
  97. switch (size)
  98. {
  99. case FileIconSize.Large:
  100. ExtractEx(fileName, iconList, null, firstIconIndex, iconCount);
  101. break;
  102. case FileIconSize.Small:
  103. ExtractEx(fileName, null, iconList, firstIconIndex, iconCount);
  104. break;
  105. default:
  106. throw new ArgumentOutOfRangeException("size");
  107. }
  108. return iconList;
  109. }
  110. public static void Extract(string fileName, List<Icon> largeIcons, List<Icon> smallIcons)
  111. {
  112. int iconCount = GetIconsCountInFile(fileName);
  113. ExtractEx(fileName, largeIcons, smallIcons, 0, iconCount);
  114. }
  115. public static List<Icon> Extract(string fileName, FileIconSize size)
  116. {
  117. int iconCount = GetIconsCountInFile(fileName);
  118. return ExtractEx(fileName, size, 0, iconCount);
  119. }
  120. public static Icon ExtractOne(string fileName, int index, FileIconSize size)
  121. {
  122. try
  123. {
  124. List<Icon> iconList = ExtractEx(fileName, size, index, 1);
  125. return iconList[0];
  126. }
  127. catch (UnableToExtractIconsException)
  128. {
  129. throw new IconNotFoundException(fileName, index);
  130. }
  131. }
  132. public static void ExtractOne(string fileName, int index, out Icon largeIcon, out Icon smallIcon)
  133. {
  134. List<Icon> smallIconList = new List<Icon>();
  135. List<Icon> largeIconList = new List<Icon>();
  136. try
  137. {
  138. ExtractEx(fileName, largeIconList, smallIconList, index, 1);
  139. largeIcon = largeIconList[0];
  140. smallIcon = smallIconList[0];
  141. }
  142. catch (UnableToExtractIconsException)
  143. {
  144. throw new IconNotFoundException(fileName, index);
  145. }
  146. }
  147. private static int GetIconsCountInFile(string fileName)
  148. {
  149. return ExtractIconEx(fileName, -1, null, null, 0);
  150. }
  151. public static Icon IconFromExtension(string extension, FileIconSize size)
  152. {
  153. if (extension[0] != '.')
  154. {
  155. extension = "." + extension;
  156. }
  157. extension = extension.ToLower();
  158. RegistryKey Root = Registry.ClassesRoot;
  159. RegistryKey ExtensionKey = Root.OpenSubKey(extension);
  160. ExtensionKey.GetValueNames();
  161. RegistryKey ApplicationKey = Root.OpenSubKey(ExtensionKey.GetValue("").ToString());
  162. string IconLocation = ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString();
  163. string[] IconPath = IconLocation.Split(',');
  164. IntPtr[] Large = null;
  165. IntPtr[] Small = null;
  166. int iIconPathNumber = 0;
  167. iIconPathNumber = ((IconPath.Length > 1) ? 1 : 0);
  168. if (IconPath[iIconPathNumber] == null)
  169. {
  170. IconPath[iIconPathNumber] = "0";
  171. }
  172. Large = new IntPtr[1];
  173. Small = new IntPtr[1];
  174. if (iIconPathNumber > 0)
  175. {
  176. ExtractIconEx(IconPath[0], Convert.ToInt16(IconPath[iIconPathNumber]), Large, Small, 1);
  177. }
  178. else
  179. {
  180. ExtractIconEx(IconPath[0], Convert.ToInt16(0), Large, Small, 1);
  181. }
  182. return (size == FileIconSize.Large) ? Icon.FromHandle(Large[0]) : Icon.FromHandle(Small[0]);
  183. }
  184. public static void ExtractInformationsFromRegistryString(string regString, out string fileName, out int index)
  185. {
  186. if (regString == null)
  187. {
  188. throw new ArgumentNullException("regString");
  189. }
  190. if (regString.Length == 0)
  191. {
  192. throw new ArgumentException("不可为空字符串.", "regString");
  193. }
  194. index = 0;
  195. string[] strArr = regString.Replace("\"", "").Split(',');
  196. fileName = strArr[0].Trim();
  197. if (strArr.Length > 1)
  198. {
  199. int.TryParse(strArr[1].Trim(), out index);
  200. }
  201. }
  202. }
  203. }