You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Python获取Windows系统中任意文件/可执行文件的图标

如何使用Python获取Windows系统中任意文件/可执行文件的图标

嘿,我完全懂你在打造替代桌面Shell时的痛点——只靠icoextract只能搞定EXE文件的图标,文件夹、Word文档还有微软商店应用这些类型的图标怎么拿确实让人头疼。我之前做类似项目时也踩过这些坑,给你分享几个实用的解决方案:

方法一:用PyWin32调用Windows Shell API(最可靠的原生方案)

Windows本身的Shell API就提供了获取任意文件图标的能力,不管是系统默认关联的图标,还是微软商店应用的图标都能搞定。你需要先安装pywin32库:

pip install pywin32

下面是一个可以获取任意文件/文件夹图标的示例代码,它会把图标保存为本地ICO文件:

import win32api
import win32gui
import win32con
import win32ui

def get_file_icon(file_path, save_path="icon.ico", icon_size=(32, 32)):
    # 根据图标尺寸选择对应标识
    flag = win32con.SHGFI_ICON | (win32con.SHGFI_LARGEICON if icon_size[0] >= 32 else win32con.SHGFI_SMALLICON)
    # 获取文件的图标信息
    shinfo = win32api.SHGetFileInfo(file_path, 0, flag)
    hicon = shinfo[0]
    
    # 创建图标绘制所需的设备上下文
    hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    hbmp = win32ui.CreateBitmap()
    hbmp.CreateCompatibleBitmap(hdc, icon_size[0], icon_size[1])
    hdc = hdc.CreateCompatibleDC()
    
    # 将图标绘制到位图中
    hdc.SelectObject(hbmp)
    hdc.DrawIcon((0, 0), hicon)
    
    # 保存为ICO文件
    hbmp.SaveBitmapFile(hdc, save_path)
    
    # 释放系统资源
    win32gui.DestroyIcon(hicon)

# 测试示例
get_file_icon("C:\\Users\\YourName\\Desktop\\test.docx", "docx_icon.ico")
get_file_icon("C:\\Users\\YourName\\Documents", "folder_icon.ico")
# 微软商店应用直接传入其URI即可
get_file_icon("ms-windows-store://pdp/?ProductId=9WZDNCRFJBMP", "store_app.ico")

这个方法的优势是原生支持所有Windows文件类型,包括微软商店应用(直接传入它们的URI即可),不需要手动处理注册表或者文件关联,省心又靠谱。

方法二:通过注册表读取文件类型的默认图标

如果不想依赖PyWin32,也可以用Python自带的winreg模块读取注册表中文件类型对应的默认图标路径。不过这个方法需要处理一些变量替换(比如注册表中的%1SystemRoot等占位符),步骤稍繁琐:

import winreg
import os

def get_default_icon_from_registry(file_extension):
    try:
        # 打开扩展名对应的注册表项
        with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, file_extension) as ext_key:
            # 获取该扩展名关联的文件类型(比如.docx对应Word.Document.12)
            file_type = winreg.QueryValue(ext_key, None)
            
            # 打开该文件类型下的DefaultIcon项
            with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, f"{file_type}\\DefaultIcon") as icon_key:
                icon_info = winreg.QueryValue(icon_key, None)
                
                # 替换路径中的系统环境变量占位符
                icon_info = os.path.expandvars(icon_info)
                # 处理类似"path.ico,0"的格式,逗号后是图标在文件中的索引
                if "," in icon_info:
                    icon_path, icon_index = icon_info.split(",", 1)
                    icon_index = int(icon_index.strip())
                else:
                    icon_path = icon_info
                    icon_index = 0
                
                return icon_path, icon_index
    except FileNotFoundError:
        # 如果找不到对应项,返回系统默认图标
        return "C:\\Windows\\System32\\shell32.dll", 0

# 测试示例
docx_icon_path, docx_icon_index = get_default_icon_from_registry(".docx")
print(f"Word文档图标路径:{docx_icon_path},索引:{docx_icon_index}")

拿到图标路径和索引后,你可以用Pillow库提取并保存图标:

pip install pillow

提取代码示例:

from PIL import Image

def extract_icon_from_file(icon_path, icon_index, save_path="icon.ico"):
    with Image.open(icon_path) as img:
        if img.format == "ICO":
            # 如果是ICO文件,直接定位到指定索引保存
            img.seek(icon_index)
            img.save(save_path)
        else:
            # 如果是DLL/EXE文件,提取对应索引的图标
            icon = img.getdata()[icon_index]
            icon.save(save_path)

# 提取Word文档图标
extract_icon_from_file(docx_icon_path, docx_icon_index, "docx_icon_reg.ico")

不过这个方法有个明显缺点:无法直接处理微软商店应用,因为它们的图标不是通过注册表关联的,所以还是更推荐第一种方法。

小提示

  • 对于微软商店应用,你可以从快捷方式的目标路径拿到类似ms-windows-store://xxx的URI,直接传入第一种方法的get_file_icon函数就能获取图标。
  • 如果需要不同尺寸的图标,只需要修改icon_size参数,比如(16,16)是系统小图标,(256,256)是高清大图标。

备注:内容来源于stack exchange,提问作者KillerRebooted

火山引擎 最新活动