2013-03-01 147 views
1

我们在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); 
     } 

回答

0

嗯,这是不是在结构适当LPStr,所以你不能试图元帅它作为一个并期望它的工作:

typedef struct _SHFILEINFO { 
    HICON hIcon; 
    int iIcon; 
    DWORD dwAttributes; 
    TCHAR szDisplayName[MAX_PATH]; 
    TCHAR szTypeName[80]; 
} SHFILEINFO; 
  • LPTStr你使用的时候你为了保存这个字符串(通常是Marshal.AllocHGlobal或类似的),我们已经分配了一块特殊的内存块,然后您将string复制到了非托管内存区域。

  • ByValTStr您在字面上按值传递实际字符串时使用,而不是通过引用内存中的另一个区域。

该结构想要适当的值,而不是指针。

+0

谢谢。一位同事在我读到你的答案之前刚刚过来解释这一点,我正准备自己回答。 – Kim 2013-03-01 20:16:01

0

我意识到这是一个古老的问题,但这帮助我解决了突然间似乎突然出现的崩溃问题。看来,在.NET 4.5.2更新通过Windows Update推出后,我开始遇到这些问题。更新前工作的为LPTStr,之后工作为ByValTStr

+0

如果问题有帮助,只需要提出问题,而不是添加答案:) – Kim 2015-08-10 03:28:01

相关问题