我們在Windows窗體應用程序中使用適當的文件圖標使用以下代碼顯示文件的樹視圖。我的問題是,調用GetIcon()似乎損壞了我的內存,因爲我開始發生各種程序崩潰,在此調用之後,我無法用調試器捕捉到這些崩潰。
當我將managedType.LPTStr
更改爲managedType.ByValTStr
時,該程序正常工作。這是一個真正的解決方案還是隻是掩蓋了問題?可以使用UnmanagedMemory.LPTStr而不是.ByValTStr導致內存損壞?爲什麼?
此代碼似乎在我們的上一個產品版本中工作,我看不到任何已更改。使用.NET 4.0。我只能在發佈模式下看到問題。
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon=IntPtr.Zero;
iIcon=0;
dwAttributes=0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPTStr, SizeConst = 260)]//works if .ByValTStr is used instead
public string szDisplayName;
[MarshalAs(UnmanagedType.LPTStr, SizeConst = 80)]//works if .ByValTStr is used instead
public string szTypeName;
};
public static Icon GetIcon(string strPath, bool bSmall)
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGFI flags;
if (bSmall)
flags = SHGFI.Icon|SHGFI.SmallIcon|SHGFI.UseFileAttributes;
else
flags = SHGFI.Icon|SHGFI.LargeIcon|SHGFI.UseFileAttributes;
SHGetFileInfo(strPath, 256, out info,(uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
}
謝謝。一位同事在我讀到你的答案之前剛剛過來解釋這一點,我正準備自己回答。 – Kim 2013-03-01 20:16:01