Question

I'm using SHGetFileInfo to retrieve certain information about a file or directory, i.e. the icon or the description the file extension.

When retrieving the description of the file extension, the string returned from SHGetFileInfo is missing the first four characters.
For example, the description of a .pdf file is Adobe Acrobat Document but I only get e Acrobat Document or the description of a .exe file is Anwendung (as I'm German, in English it's Application i suppose), but I only get ndung.

I'm using

public static string GetFileTypeDescription(this FileInfo file)
{
    SHFILEINFO shFileInfo;
    if (SHGetFileInfo(
          file.Extension, 
          SHGFI_FILE_ATTRIBUTE_NORMAL, 
          out shFileInfo, 
          (uint)Marshal.SizeOf(typeof(SHFILEINFO)), 
          SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME)
            != IntPtr.Zero)
    {
        return shFileInfo.szTypeName;
    }

    return null;
}

with the usual implementation of SHGetFileInfo:

[DllImport("shell32.dll")]
internal static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

[StructLayout(LayoutKind.Sequential)]
internal struct SHFILEINFO
{
    public IntPtr hIcon;
    public IntPtr iIcon;
    public uint dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string szTypeName;
};

//I omitted all flags which are not used above
private const uint SHGFI_FILE_ATTRIBUTE_NORMAL = 0x80,
                   SHGFI_USEFILEATTRIBUTES = 0x10,
                   SHGFI_TYPENAME = 0x400;

What is wrong? Did I miss something? Or how can I retrieve the full description?

Was it helpful?

Solution

The iIcon field in the C++ struct has type int. On Windows that is a 4 byte signed integer. It corresponds to int in C#.

You have declared the field as IntPtr in your C# code. That is a signed integer, the same size as a pointer. So it is 4 bytes in 32 bit code, and 8 bytes in 64 bit code. It seems likely that you are running 64 bit code.

So, the error is the declaration of this field which simply has the wrong type. The solution is to change the type of iIcon to int.

OTHER TIPS

Change IntPtr on the iIcon to int. That should work. Or use x86 as the platform target. Either of the two.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top