具有CharSet的DllImport属性不适用于.NET4.0

时间:2013-11-20 05:20:13

标签: c# .net dllimport

我正在尝试使用DllImport在我的C#代码中使用SHGetFileInfo方法。

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

现在这与不同的dot net框架有不同的行为。如果我在4.5框架应用程序的机器上运行我的应用程序工作正常。但是如果在框架4.0应用程序崩溃的机器上运行相同的应用程序。

如果我从DllImport属性应用程序中删除Charset,则在4.0和4.5框架上运行正常。

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

现在MSDN谈到它对不同框架的支持。

.NET Framework 受以下支持:4.5,4,3.5,3.0,2.0,1.1,1.0

.NET Framework客户端配置文件 受以下支持:4,3.5 SP1

便携式类库 受以下版本支持:可移植类库

.NET for Windows Store应用程序 受以下版本支持:Windows 8

为什么它不能在4.0框架的机器上运行?

这是完整的代码:

[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 个答案:

答案 0 :(得分:1)

iIcon应该是int,而不是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;
};

您可能看到的差异是因为AnyCPU的较新的默认编译选项显示"prefer 32-bit"。因此,4.5代码可能以32位运行,其中IntPtrint的大小相同。