Search code examples
c#unicodepinvoke

How to pinvoke unicode version of SHGetFileInfo (c#)?


I tried this:

public struct SHFILEINFOW
            {
                public IntPtr hIcon;
                public int iIcon;
                public uint dwAttributes;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260 * 2)]
                public string szDisplayName;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80 * 2)]
                public string szTypeName;
            }
    [DllImport("shell32.dll")]
            public static extern IntPtr SHGetFileInfoW(IntPtr pIDL, uint dwFileAttributes, out SHFILEINFOW psfi, uint cbFileInfo, SHGFI uFlags);
    String DisplayName = shInfoW.szDisplayName;

But DisplayName contain only the first char


Solution

  •    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260 * 2)]
    

    ByValTStr means "same as the class or structure". But you didn't specify the CharSet attribute for the structure. It defaults to CharSet.Ansi so the string is getting marshaled as though it was a 8-bit character string. Since the real string is Unicode, you'll indeed get very high odds for only getting the first character. Fix:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHFILEINFOW {
       // etc...
    }