1

我们在 Windows 窗体应用程序中有一个树视图,它使用以下代码使用适当的文件图标显示文件。我的问题是对 GetIcon() 的调用似乎破坏了我的记忆,因为我开始遇到各种程序崩溃,在此调用之后我无法用调试器捕获这些崩溃。
当我更改managedType.LPTStrmanagedType.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);
        }
4

2 回答 2

0

好吧,它LPStr在结构中不是正确的,因此您不能尝试将其编组为一个并期望它起作用:

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

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

该结构需要正确的值,而不是指针。

于 2013-03-01T20:12:37.680 回答
0

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

于 2015-08-07T21:33:31.480 回答