代码之家  ›  专栏  ›  技术社区  ›  Chris Wright

方法在3310次成功后失败

  •  4
  • Chris Wright  · 技术社区  · 7 年前

    我继承了以下扩展方法,该方法基于文件路径创建ImageSource对象

    public static class ImageSourceExtensions
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        };
    
        public const uint SHGFI_ICON = 0x100;
        public const uint SHGFI_LARGEICON = 0x0;
    
        [DllImport("shell32.dll")]
        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
    
        public static ImageSource GetIconFromFolder(this string filePath)
        {
            SHFILEINFO shinfo = new SHFILEINFO();
            SHGetFileInfo(filePath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo),
                    SHGFI_ICON | SHGFI_LARGEICON);
    
            using (Icon i = Icon.FromHandle(shinfo.hIcon))
            {
                //Convert icon to a Bitmap source
                ImageSource img = Imaging.CreateBitmapSourceFromHIcon(
                                        i.Handle,
                                        new Int32Rect(0, 0, i.Width, i.Height),
                                        BitmapSizeOptions.FromEmptyOptions());
    
                return img;
            }
        }
    }
    

    '传递给图标的Win32句柄无效或错误 类型'

    当使用 所有物

    这个错误最初是在我的主应用程序中抛出的,每次都在不同的文件中。此后,我将该类提取到一个新项目中,通过单击按钮可以抛出相同的错误(在相同次数之后):

    String path = @"C:\Generic Folder\Generic Document.pdf";
    
            for (int i = 0; i <4000; i++)
            {
                ImageSource img = path.GetIconFromFolder();
            }
    

    有谁知道这件事的明显原因吗?

    1 回复  |  直到 7 年前
        1
  •  6
  •   nvoigt    7 年前

    你用完了 HANDLE s、 Windows有有限数量的句柄,当您获得一个句柄(在本例中是图标的句柄)时,您需要在不再使用它后释放它。如果不这样做,Windows将没有可用的手柄。

    如果SHGetFileInfo在psfi指向的SHFILEINFO结构的hIcon成员中返回图标句柄, 当你不再需要它时,你有责任用DestroyIcon释放它 .

    所以你需要PInvoke DestroyIcon 然后把你的 shinfo.hIcon 在你的功能结束时。

    使用创建的图标的处理 FromHandle 不会破坏原始句柄: