2013-03-01 148 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

相關問題