PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Main/ScriptIDE.Base/SysModules/sys_IconFromFileExt.vb

https://github.com/max-weller/ScriptIDE
Visual Basic | 322 lines | 209 code | 56 blank | 57 comment | 0 complexity | 33f69b7c5c952979fa6376490e164b61 MD5 | raw file
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.Collections
  4. Imports System.Text
  5. Imports System.Runtime.InteropServices
  6. Imports Microsoft.Win32
  7. Imports System.Drawing
  8. Namespace FileTypeAndIcon
  9. ''' <summary>
  10. ''' Structure that encapsulates basic information of icon embedded in a file.
  11. ''' </summary>
  12. Public Structure EmbeddedIconInfo
  13. Public FileName As String
  14. Public IconIndex As Integer
  15. End Structure
  16. Public Class RegisteredFileType
  17. Private Shared iconCache As New Dictionary(Of String, Icon())
  18. Shared Sub clearCache()
  19. iconCache.Clear()
  20. End Sub
  21. #Region "APIs"
  22. Private Structure SHFILEINFO
  23. Public hIcon As IntPtr ' : icon
  24. Public iIcon As Integer ' : icondex
  25. Public dwAttributes As Integer ' : SFGAO_ flags
  26. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
  27. Public szDisplayName As String
  28. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
  29. Public szTypeName As String
  30. End Structure
  31. Private Declare Auto Function SHGetFileInfo Lib "shell32.dll" _
  32. (ByVal pszPath As String, _
  33. ByVal dwFileAttributes As Integer, _
  34. ByRef psfi As SHFILEINFO, _
  35. ByVal cbFileInfo As Integer, _
  36. ByVal uFlags As Integer) As IntPtr
  37. Private Const SHGFI_ICON = &H100
  38. Enum assoc_iconSize
  39. SHGFI_SMALLICON = &H1
  40. SHGFI_LARGEICON = &H0 ' Large icon
  41. End Enum
  42. Private Declare Ansi Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Integer, ByVal lpszExeFileName As String, ByVal nIconIndex As Integer) As IntPtr
  43. <DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
  44. Private Shared Function ExtractIconEx(ByVal szFileName As String, ByVal nIconIndex As Integer, ByVal phiconLarge As IntPtr(), ByVal phiconSmall As IntPtr(), ByVal nIcons As UInteger) As UInteger
  45. End Function
  46. <DllImport("user32.dll", EntryPoint:="DestroyIcon", SetLastError:=True)> _
  47. Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As Integer
  48. End Function
  49. #End Region
  50. #Region "CORE METHODS"
  51. ''' <summary>
  52. ''' Gets registered file types and their associated icon in the system.
  53. ''' </summary>
  54. ''' <returns>Returns a hash table which contains the file extension as keys, the icon file and param as values.</returns>
  55. Public Shared Function GetAllFileTypesAndIcons() As Hashtable
  56. Try
  57. ' Create a registry key object to represent the HKEY_CLASSES_ROOT registry section
  58. Dim rkRoot As RegistryKey = Registry.ClassesRoot
  59. 'Gets all sub keys' names.
  60. Dim keyNames As String() = rkRoot.GetSubKeyNames()
  61. Dim iconsInfo As New Hashtable()
  62. 'Find the file icon.
  63. For Each keyName As String In keyNames
  64. If [String].IsNullOrEmpty(keyName) Then
  65. Continue For
  66. End If
  67. Dim indexOfPoint As Integer = keyName.IndexOf(".")
  68. 'If this key is not a file exttension(eg, .zip), skip it.
  69. If indexOfPoint <> 0 Then
  70. Continue For
  71. End If
  72. Dim rkFileType As RegistryKey = rkRoot.OpenSubKey(keyName)
  73. If rkFileType Is Nothing Then
  74. Continue For
  75. End If
  76. 'Gets the default value of this key that contains the information of file type.
  77. Dim defaultValue As Object = rkFileType.GetValue("")
  78. If defaultValue Is Nothing Then
  79. Continue For
  80. End If
  81. 'Go to the key that specifies the default icon associates with this file type.
  82. Dim defaultIcon As String = defaultValue.ToString() & "\DefaultIcon"
  83. Dim rkFileIcon As RegistryKey = rkRoot.OpenSubKey(defaultIcon)
  84. If rkFileIcon IsNot Nothing Then
  85. 'Get the file contains the icon and the index of the icon in that file.
  86. Dim value As Object = rkFileIcon.GetValue("")
  87. If value IsNot Nothing Then
  88. 'Clear all unecessary " sign in the string to avoid error.
  89. Dim fileParam As String = value.ToString().Replace("""", "")
  90. iconsInfo.Add(keyName, fileParam)
  91. End If
  92. rkFileIcon.Close()
  93. End If
  94. rkFileType.Close()
  95. Next
  96. rkRoot.Close()
  97. Return iconsInfo
  98. Catch exc As Exception
  99. Throw exc
  100. End Try
  101. End Function
  102. ''' <summary>
  103. ''' Gets a registered file types and their associated icon in the system by its file ext
  104. ''' </summary>
  105. ''' <returns>Returns a hash table which contains the file extension as keys, the icon file and param as values.</returns>
  106. Public Shared Function GetFileIconByExt(ByVal fileExt As String) As Icon()
  107. Try
  108. fileExt = fileExt.ToLower
  109. If fileExt.StartsWith(".") = False And fileExt <> "folder" Then fileExt = "." + fileExt
  110. If iconCache.ContainsKey(fileExt) AndAlso iconCache(fileExt)(0) IsNot Nothing Then Return iconCache(fileExt)
  111. ' Create a registry key object to represent the HKEY_CLASSES_ROOT registry section
  112. Dim rkRoot As RegistryKey = Registry.ClassesRoot
  113. Dim data = New Icon() {My.Resources.invalidicon, My.Resources.invalidicon}
  114. Dim rkFileType As RegistryKey = rkRoot.OpenSubKey(fileExt)
  115. If rkFileType Is Nothing Then
  116. Return data
  117. End If
  118. 'Gets the default value of this key that contains the information of file type.
  119. Dim defaultValue As Object = rkFileType.GetValue("")
  120. If defaultValue Is Nothing Then
  121. Return data
  122. End If
  123. 'Go to the key that specifies the default icon associates with this file type.
  124. Dim defaultIcon As String = defaultValue.ToString() & "\DefaultIcon"
  125. Dim rkFileIcon As RegistryKey = rkRoot.OpenSubKey(defaultIcon)
  126. If rkFileIcon IsNot Nothing Then
  127. 'Get the file contains the icon and the index of the icon in that file.
  128. Dim value As Object = rkFileIcon.GetValue("")
  129. If value IsNot Nothing Then
  130. 'Clear all unecessary " sign in the string to avoid error.
  131. Dim fileParam As String = value.ToString().Replace("""", "")
  132. data = New Icon() {ExtractIconFromFile(fileParam, False), ExtractIconFromFile(fileParam, True)}
  133. iconCache.Add(fileExt, data)
  134. Else
  135. iconCache.Add(fileExt, data)
  136. End If
  137. rkFileIcon.Close()
  138. Else
  139. iconCache.Add(fileExt, data)
  140. End If
  141. closeKeys:
  142. rkFileType.Close()
  143. rkRoot.Close()
  144. Return Data
  145. Catch exc As Exception
  146. Return New Icon() {My.Resources.invalidicon, My.Resources.invalidicon}
  147. End Try
  148. End Function
  149. ''' <summary>
  150. ''' Extract the icon from file.
  151. ''' </summary>
  152. ''' <param name="fileAndParam">The params string,
  153. ''' such as ex: "C:\\Program Files\\NetMeeting\\conf.exe,1".</param>
  154. ''' <returns>This method always returns the large size of the icon (may be 32x32 px).</returns>
  155. Public Shared Function ExtractIconFromFile(ByVal fileAndParam As String) As Icon
  156. Try
  157. Dim embeddedIcon As EmbeddedIconInfo = getEmbeddedIconInfo(fileAndParam)
  158. 'Gets the handle of the icon.
  159. Dim lIcon As IntPtr = ExtractIcon(0, embeddedIcon.FileName, embeddedIcon.IconIndex)
  160. 'Gets the real icon.
  161. Return Icon.FromHandle(lIcon)
  162. Catch exc As Exception
  163. Throw exc
  164. End Try
  165. End Function
  166. ''' <summary>
  167. ''' Extract the icon from file.
  168. ''' </summary>
  169. ''' <param name="fileAndParam">The params string,
  170. ''' such as ex: "C:\\Program Files\\NetMeeting\\conf.exe,1".</param>
  171. ''' <param name="isLarge">
  172. ''' Determines the returned icon is a large (may be 32x32 px)
  173. ''' or small icon (16x16 px).</param>
  174. Public Shared Function ExtractIconFromFile(ByVal fileAndParam As String, ByVal isLarge As Boolean) As Icon
  175. Dim readIconCount As UInteger = 0
  176. Dim hDummy As IntPtr() = New IntPtr(0) {IntPtr.Zero}
  177. Dim hIconEx As IntPtr() = New IntPtr(0) {IntPtr.Zero}
  178. Try
  179. Dim embeddedIcon As EmbeddedIconInfo = getEmbeddedIconInfo(fileAndParam)
  180. If isLarge Then
  181. readIconCount = ExtractIconEx(embeddedIcon.FileName, embeddedIcon.IconIndex, hIconEx, hDummy, 1)
  182. Else
  183. readIconCount = ExtractIconEx(embeddedIcon.FileName, embeddedIcon.IconIndex, hDummy, hIconEx, 1)
  184. End If
  185. If readIconCount > 0 AndAlso hIconEx(0) <> IntPtr.Zero Then
  186. ' Get first icon.
  187. Dim extractedIcon As Icon = DirectCast(Icon.FromHandle(hIconEx(0)).Clone(), Icon)
  188. Return extractedIcon
  189. Else
  190. ' No icon read
  191. Return My.Resources.invalidicon
  192. End If
  193. Catch exc As Exception
  194. ' Extract icon error.
  195. Throw New ApplicationException("Could not extract icon", exc)
  196. Finally
  197. ' Release resources.
  198. For Each ptr As IntPtr In hIconEx
  199. If ptr <> IntPtr.Zero Then
  200. DestroyIcon(ptr)
  201. End If
  202. Next
  203. For Each ptr As IntPtr In hDummy
  204. If ptr <> IntPtr.Zero Then
  205. DestroyIcon(ptr)
  206. End If
  207. Next
  208. End Try
  209. End Function
  210. #End Region
  211. Shared Function GetAssociatedIcon(ByVal fileSpec As String, _
  212. Optional ByVal iconSize As assoc_iconSize = assoc_iconSize.SHGFI_LARGEICON _
  213. ) As Image
  214. Dim hImg As IntPtr 'The handle to the system image list.
  215. Dim shinfo As SHFILEINFO
  216. shinfo = New SHFILEINFO()
  217. hImg = SHGetFileInfo(fileSpec, 0, shinfo, _
  218. Marshal.SizeOf(shinfo), _
  219. SHGFI_ICON Or iconSize)
  220. 'The icon is returned in the hIcon member of the
  221. 'shinfo struct.
  222. Dim myIcon As System.Drawing.Icon
  223. If shinfo.hIcon = 0 Then Return Workbench.Instance.Icon.ToBitmap
  224. myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon)
  225. Return myIcon.ToBitmap
  226. End Function
  227. #Region "UTILITY METHODS"
  228. ''' <summary>
  229. ''' Parses the parameters string to the structure of EmbeddedIconInfo.
  230. ''' </summary>
  231. ''' <param name="fileAndParam">The params string,
  232. ''' such as ex: "C:\\Program Files\\NetMeeting\\conf.exe,1".</param>
  233. ''' <returns></returns>
  234. Protected Shared Function getEmbeddedIconInfo(ByVal fileAndParam As String) As EmbeddedIconInfo
  235. Dim embeddedIcon As New EmbeddedIconInfo()
  236. If [String].IsNullOrEmpty(fileAndParam) Then
  237. Return embeddedIcon
  238. End If
  239. 'Use to store the file contains icon.
  240. Dim fileName As String = [String].Empty
  241. 'The index of the icon in the file.
  242. Dim iconIndex As Integer = 0
  243. Dim iconIndexString As String = [String].Empty
  244. Dim commaIndex As Integer = fileAndParam.IndexOf(",")
  245. 'if fileAndParam is some thing likes that: "C:\\Program Files\\NetMeeting\\conf.exe,1".
  246. If commaIndex > 0 Then
  247. fileName = fileAndParam.Substring(0, commaIndex)
  248. iconIndexString = fileAndParam.Substring(commaIndex + 1)
  249. Else
  250. fileName = fileAndParam
  251. End If
  252. If Not [String].IsNullOrEmpty(iconIndexString) Then
  253. 'Get the index of icon.
  254. iconIndex = Integer.Parse(iconIndexString)
  255. If iconIndex < 0 Then
  256. iconIndex = 0
  257. 'To avoid the invalid index.
  258. End If
  259. End If
  260. embeddedIcon.FileName = fileName
  261. embeddedIcon.IconIndex = iconIndex
  262. Return embeddedIcon
  263. End Function
  264. #End Region
  265. End Class
  266. End Namespace