如何在C#中获取当前活动窗口的图标
实现思路
要获取活动窗口的图标,核心是先拿到活动窗口的句柄,再通过Win32 API读取对应窗口的图标资源,步骤如下:
- 首先调用
GetForegroundWindow()Win32 API获取当前活动窗口的句柄,这一步和你用ActiveWindowTitle()底层获取窗口的逻辑是一致的,确保拿到的是同一个窗口 - 调用
SendMessageAPI向窗口句柄发送WM_GETICON消息,获取窗口的图标句柄,你可以选择获取大图标(ICON_BIG)或者小图标(ICON_SMALL) - 拿到图标句柄后,用
Icon.FromHandle()方法将Win32图标句柄转换为C#的System.Drawing.Icon对象,就可以直接使用了
完整实现代码
首先需要先导入Win32 API的声明,示例代码如下:
using System; using System.Drawing; using System.Runtime.InteropServices; public class ActiveWindowIconHelper { // Win32 API 导入 [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); // 常量定义 private const uint WM_GETICON = 0x007F; private const IntPtr ICON_SMALL = (IntPtr)0; private const IntPtr ICON_BIG = (IntPtr)1; /// <summary> /// 获取当前活动窗口的图标 /// </summary> /// <param name="getBigIcon">是否获取大图标,true为大图标,false为小图标</param> /// <returns>活动窗口的Icon对象,获取失败返回null</returns> public static Icon GetActiveWindowIcon(bool getBigIcon = false) { IntPtr hWnd = GetForegroundWindow(); if (hWnd == IntPtr.Zero) return null; IntPtr iconHandle = SendMessage(hWnd, WM_GETICON, getBigIcon ? ICON_BIG : ICON_SMALL, IntPtr.Zero); // 部分窗口没有主动设置图标时,尝试获取类的默认图标 if (iconHandle == IntPtr.Zero) iconHandle = GetClassLongPtr(hWnd, getBigIcon ? -14 /*GCLP_HICON*/ : -34 /*GCLP_HICONSM*/); if (iconHandle == IntPtr.Zero) return null; return Icon.FromHandle(iconHandle); } // 兼容32/64位系统的GetClassLongPtr声明 [DllImport("user32.dll", EntryPoint = "GetClassLong")] private static extern IntPtr GetClassLong32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] private static extern IntPtr GetClassLong64(IntPtr hWnd, int nIndex); private static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) { return IntPtr.Size == 8 ? GetClassLong64(hWnd, nIndex) : GetClassLong32(hWnd, nIndex); } }
使用示例
// 获取活动窗口大图标 Icon activeWindowIcon = ActiveWindowIconHelper.GetActiveWindowIcon(true); if (activeWindowIcon != null) { // 可直接赋值给PictureBox控件显示,或者保存为.ico文件 pictureBox1.Image = activeWindowIcon.ToBitmap(); }
注意事项
- 项目需要添加
System.Drawing程序集的引用,如果是.NET Core/.NET 5+项目,需要安装NuGet包System.Drawing.Common - 部分权限受限的系统窗口可能无法获取到图标,这种情况返回null为正常现象
- 不需要手动释放Icon的句柄,
Icon.FromHandle创建的对象会由.NET运行时自动管理资源
内容的提问来源于stack exchange,提问作者Yamin Official
相关产品推荐
相关产品推荐

