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

发布于 2024-11-27 02:51:22 字数 39 浏览 0 评论 0原文

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

How can I use the images within shell32.dll in my C# project?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

勿忘心安 2024-12-04 02:51:22

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

You can extract icons from a DLL with this code:

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

Of course you need to know the index of the image in the DLL...

九局 2024-12-04 02:51:22

此帖子 MSDN开发者论坛上提供了解决方案:

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

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

This thread on the MSDN developer forums offers a solution:

The typical way to implement these in .NET is to use the graphics provided in the ZIP file located at C:\Program Files\Microsoft Visual Studio X\Common7\VS200XImageLibrary.

You don't state which version of Visual Studio you have installed but you'll need to replace the "200X" with your version number.

默嘫て 2024-12-04 02:51:22

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

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

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

The code in the accepted answer leaks one icon handle each time it's called, as it always asks for two icon handles and only gives one back.

Here is a version that doesn't leak a handle:

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);
善良天后 2024-12-04 02:51:22

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

Some of them are available in %Program Files%\Microsoft Visual Studio 10.0\Common7\VS2010ImageLibrary - for others, you'd need to speak to Microsoft's lawyers about licensing them for redistribution in your application

冷血 2024-12-04 02:51:22

请参阅此代码。这将会有帮助

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

See this code. It will be help

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);
    }
}
々眼睛长脚气 2024-12-04 02:51:22

对于任何正在寻找更新/完整解决方案的人来说,我已经创建了一个 WinUI 实用程序此处

For anyone stumbling across this who is looking for an updated/complete solution I have created a WinUI utility here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文