【问题标题】:How can I use the images within shell32.dll in my C# project?如何在我的 C# 项目中使用 shell32.dll 中的图像?
【发布时间】:2011-07-29 12:20:17
【问题描述】:

如何在我的 C# 项目中使用 shell32.dll 中的图像?

【问题讨论】:

    标签: c# shell32.dll


    【解决方案1】:

    您可以使用以下代码从 DLL 中提取图标:

    public class IconExtractor
    {
    
        public static Icon Extract(string file, int number, bool largeIcon)
        {
            IntPtr large;
            IntPtr small;
            ExtractIconEx(file, number, out large, out small, 1);
            try
            {
                return Icon.FromHandle(largeIcon ? large : small);
            }
            catch
            {
                return null;
            }
    
        }
        [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
    
    }
    
    ...
    
    form.Icon = IconExtractor.Extract("shell32.dll", 42, true);
    

    当然要知道图片在DLL中的索引...

    【讨论】:

      【解决方案2】:

      MSDN 开发者论坛上的This thread 提供了一个解决方案:

      在 .NET 中实现这些的典型方法是使用位于 C:\Program Files\Microsoft Visual Studio X\Common7\VS200XImageLibrary 的 ZIP 文件中提供的图形。

      您没有说明您安装了哪个版本的 Visual Studio,但您需要将“200X”替换为您的版本号。

      【讨论】:

      • “这些图形不包含在 Express Edition 中。”
      • @endolith - 8 年来我没有必要重新审视这个答案,所以如果事情继续发展,我就不会更新答案。也许我们需要将此问题作为您找到的问题的副本来结束。
      【解决方案3】:

      接受的答案中的代码每次调用时都会泄漏一个图标句柄,因为它总是要求两个图标句柄并且只返回一个。

      这是一个不泄漏句柄的版本:

      public static Icon Extract(string filePath, int index, bool largeIcon = true)
      {
          if (filePath == null)
              throw new ArgumentNullException(nameof(filePath));
      
          IntPtr hIcon;
          if (largeIcon)
          {
              ExtractIconEx(filePath, index, out hIcon, IntPtr.Zero, 1);
          }
          else
          {
              ExtractIconEx(filePath, index, IntPtr.Zero, out hIcon, 1);
          }
      
          return hIcon != IntPtr.Zero ? Icon.FromHandle(hIcon) : null;
      }
      
      [DllImport("shell32", CharSet = CharSet.Unicode)]
      private static extern int ExtractIconEx(string lpszFile, int nIconIndex, out IntPtr phiconLarge, IntPtr phiconSmall, int nIcons);
      
      [DllImport("shell32", CharSet = CharSet.Unicode)]
      private static extern int ExtractIconEx(string lpszFile, int nIconIndex, IntPtr phiconLarge, out IntPtr phiconSmall, int nIcons);
      

      【讨论】:

        【解决方案4】:

        查看此代码。会有帮助的

        public class ExtractIcon
        {
            [DllImport("Shell32.dll")]
            private static extern int SHGetFileInfo(
                string pszPath, uint dwFileAttributes,
                out SHFILEINFO psfi, uint cbfileInfo,
                SHGFI uFlags);
        
            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;
                public string szDisplayName;
                public string szTypeName;
            };
        
            private enum SHGFI
            {
                SmallIcon = 0x00000001,
                OpenIcon = 0x00000002,
                LargeIcon = 0x00000000,
                Icon = 0x00000100,
                DisplayName = 0x00000200,
                Typename = 0x00000400,
                SysIconIndex = 0x00004000,
                LinkOverlay = 0x00008000,
                UseFileAttributes = 0x00000010
            }
        
            public static Icon GetIcon(string strPath, bool bSmall, bool bOpen)
            {
                SHFILEINFO info = new SHFILEINFO(true);
                int cbFileInfo = Marshal.SizeOf(info);
                SHGFI flags;
        
                if (bSmall)
                    flags = SHGFI.Icon | SHGFI.SmallIcon;
                else
                    flags = SHGFI.Icon | SHGFI.LargeIcon;
        
                if (bOpen) flags = flags | SHGFI.OpenIcon;
        
                SHGetFileInfo(strPath, 0, out info, (uint)cbFileInfo, flags);
        
                return Icon.FromHandle(info.hIcon);
            }
        }
        

        【讨论】:

          【解决方案5】:

          其中一些可在 %Program Files%\Microsoft Visual Studio 10.0\Common7\VS2010ImageLibrary 中找到 - 对于其他人,您需要与 Microsoft 的律师讨论许可他们在您的应用程序中重新分发

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-22
            • 1970-01-01
            • 1970-01-01
            • 2014-08-02
            • 1970-01-01
            • 1970-01-01
            • 2017-03-18
            • 1970-01-01
            相关资源
            最近更新 更多