1
votes

I am trying to use SHGetFileInfo method in my C# code using DllImport.

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

Now this has different behaviors with different dot net framework. If I run my application on a machine with 4.5 framework application works fine. But If run the same application on a machine with framework 4.0 application crashes.

If I remove the Charset from DllImport attribute application runs fine on 4.0 and 4.5 frameworks.

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.charset(v=vs.110).aspx

Now MSDN says about its support on different frameworks.

.NET Framework Supported in: 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile Supported in: 4, 3.5 SP1

Portable Class Library Supported in: Portable Class Library

.NET for Windows Store apps Supported in: Windows 8

Why it is not running on machine with 4.0 framework?

Here is complete code:

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

internal static class SafeNativeMethods
{
    public const uint SHGFI_ICON = 0x100;
    public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
    public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

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

public IconHelperClass
{
    var shinfo = new SHFILEINFO();
    SafeNativeMethods.SHGetFileInfo(iconPath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), flag);
}
1
Include the definition of SHFILEINFO and the code at your call site.William
@William I have added that code, and I am calling this method in my code. Problem is that code works fine for 4.5 framework but crashes for 4.0 framework.fhnaseer
I meant to include it in your content of your question. Also include the text of the exception that occurs.William
What happens if you force your code to be 32-bit?Damien_The_Unbeliever
@Damien_The_Unbeliever You mean changing whole application to 32bit?,fhnaseer

1 Answers

1
votes

iIcon should be an int, not an IntPtr:

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

The difference you're likely seeing is because of the newer default compilation option for AnyCPU which says "prefer 32-bit". So the 4.5 code is likely running as 32-bit where the size of IntPtr and int are the same.