SHGetFileInfo:文件扩展名的描述太短

时间:2013-11-22 18:48:50

标签: c# winforms .net-4.0 pinvoke dllimport

我正在使用SHGetFileInfo来检索有关文件或目录的某些信息,即图标或文件扩展名的描述。

检索文件扩展名的描述时,从SHGetFileInfo返回的字符串缺少前四个字符。
例如,.pdf文件的说明为Adobe Acrobat Document,但我只获得e Acrobat Document.exe文件的描述为Anwendung(因为我是德语,英语是Application我想的,但我只得到ndung

我正在使用

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;
}

通常实现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;

有什么问题?我错过了什么?或者我如何检索完整描述?

2 个答案:

答案 0 :(得分:2)

C ++结构中的iIcon字段的类型为int。在Windows上,这是一个4字节有符号整数。它对应于C#中的int。

您已在C#代码中将该字段声明为IntPtr。这是一个有符号整数,与指针大小相同。因此,32位代码为4个字节,64位代码为8个字节。您似乎正在运行64位代码。

所以,错误是这个字段的声明,它只是错误的类型。解决方案是将iIcon的类型更改为int。

答案 1 :(得分:0)

将iIcon上的IntPtr更改为int。这应该工作。或者使用x86作为平台目标。两者中的任何一个。