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

本文关键字:dll shell32 图像 我的 项目 | 更新日期: 2023-09-27 18:04:09

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

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

您可以使用以下代码从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中图像的索引…

MSDN开发者论坛上的这个帖子提供了一个解决方案:

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

你没有说明你安装的是哪个版本的Visual Studio,但是你需要用你的版本号替换"200X"。

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

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

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);

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

查看此代码。这会有帮助的

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);
    }
}