views:

319

answers:

2

Hi,

There are several approaches to fetch the description and default icon for a given extension (no full path), e.g for "*.doc" I want to get "Microsoft Word Document" and the related icon, which do you think will be the fastest one of the following:

  1. Search the registry:

    • in registry, go to "HKCR.{extension}", read the default value (let's call it filetype)
    • in "HKCR{filetype}\DefaultIcon", read the default value: this is the path to the icon file (or icon container file, like an .exe with an embedded icon resource)
    • if needed, use your preferred method of extracting the icon resource out of the mentioned file.
  2. Call API ShGetFileInfo. I believe this is a bit slow.

  3. According to Rob, here: http://stackoverflow.com/questions/829843/how-to-get-icon-and-description-from-file-extension-using-delphi

Calls the IExtractIcon interface a "more flexible and efficient" alternative. But the sequence it recommends is to use an IShellFolder interface, then call GetUIObjectOf to get the file's IExtractIcon interface, and then call GetIconLocation and Extract on it to retrieve the icon's handle. (but this method cannot read the extension description?)

Since the speed is very important because I need to read the info for all the file types in the system.

Thank you very much!

+2  A: 

Firstly: Are you getting millions of icons? If you're ony getting one or a few hundred, then does it really matter which is fastest? How slow is too slow? THe best way is to try the code and time it to see if it's worth worrying about.

Secondly: Is the speed difference really a problem? Using SHGetFileInfo is more likely to work on every operating system version and will be compatible with however Microsoft do things in future - Reading the registry may not work in some cases. How will you test it?

Finally, having weighed up the above questions, the best approach is to write the 10 lines of code that it will take to try all three approaches and simply see which one is fastest.

Jason Williams
+1 for "Test test and test again"
thijs
A: 

Call SHGetFileInfo for both description and icon. From experience I can tell you that accessing and searching the registry is slow. I do not know exactly how slow. BUT, I had to cache results to avoid accessing the registry. In addition, reliably retrieving file information for all file types is not as simple as you describe in Item #1. Let SHGetFileInfo do the work for you reliably and cache results to improve performance as shown below with the file's type name.

Moreove, see How to use the SHGetFileInfo function to get the icons that are associated with files in Visual Basic .NET at http://support.microsoft.com/kb/319340 for an easy way of retrieving the icon.

Private Shared _descriptions As New Dictionary(Of String, String)

Private Shared Function CacheDocumentDescription(ByVal extension As String, ByVal description As String) As String
    _descriptions.Add(extension, description)
    DumpCacheDocumentItem(extension, description, "added")
    Return description
End Function

<Conditional("DbCacheDocument")> _
Private Shared Sub DumpCacheDocumentItem(ByVal extension As String, ByVal description As String, ByVal category As String)
    Debug.WriteLine(extension & ", " & description, category)
End Sub

Public Shared Function GetTypeName(ByVal fullPath As String) As String

    Dim sExt As String = System.IO.Path.GetExtension(fullPath)

    If Len(sExt) = 0 Then
        Return "File"
    End If

    If _descriptions.ContainsKey(sExt) Then
        'return cached value
        Return _descriptions.Item(sExt)
    End If

    Dim sDocDescription As String = Missico.Shell.ShellFileInfo.TypeName(fullPath)

    Return CacheDocumentDescription(sExt, sDocDescription)
End Function
AMissico

related questions