You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux环境下使用Python pefile库获取PE文件产品名称的问题咨询

问题分析与解决方案

你的代码忽略了VS_VERSIONINFO结构的嵌套层次——在pefile中,StringTable并不是直接挂在FileInfo条目下的,而是嵌套在StringFileInfo子结构里。Notepad.exe的版本信息正是按照这个标准结构存储的,所以你的遍历逻辑跳过了关键的StringFileInfo层,导致找不到目标数据。

另外还要注意,pefile返回的版本信息字符串可能是字节类型,需要根据Windows版本资源的标准编码(UTF-16LE)解码成Unicode字符串,避免出现乱码问题。

修正后的完整代码

下面是可以正确获取Notepad.exe(以及绝大多数Windows PE文件)详细信息的代码,包含你需要的文件描述、产品名称、原始文件名等字段:

from pefile import PE
from typing import Optional, Dict

def get_pe_version_info(pe_path: str) -> Optional[Dict[str, str]]:
    try:
        pe = PE(pe_path)
    except Exception as e:
        print(f"解析PE文件失败: {e}")
        return None

    # 检查是否存在版本信息结构
    if not hasattr(pe, 'VS_VERSIONINFO') or not hasattr(pe, 'FileInfo'):
        return None

    version_info = {}
    # 遍历VS_VERSIONINFO结构
    for entry in pe.FileInfo:
        # 只处理包含StringFileInfo的条目
        if hasattr(entry, 'StringFileInfo'):
            for string_file_info in entry.StringFileInfo:
                # 遍历每个语言/代码页对应的StringTable
                for string_table in string_file_info.StringTable:
                    # 解码字节串为Unicode字符串
                    for key, value in string_table.entries.items():
                        if isinstance(value, bytes):
                            try:
                                # Windows版本信息通常使用UTF-16LE编码
                                decoded_value = value.decode('utf-16le')
                            except UnicodeDecodeError:
                                # 解码失败时回退到系统默认编码
                                decoded_value = value.decode('mbcs')
                        else:
                            decoded_value = value
                        version_info[key] = decoded_value
    return version_info

# 示例用法
if __name__ == "__main__":
    info = get_pe_version_info("notepad.exe")
    if info:
        print("文件描述:", info.get("FileDescription"))
        print("产品名称:", info.get("ProductName"))
        print("原始文件名:", info.get("OriginalFilename"))
        print("文件版本:", info.get("FileVersion"))
        print("产品版本:", info.get("ProductVersion"))

关键改进点说明

  • 修正结构遍历层次:新增了entry.StringFileInfo的遍历,这是访问StringTable的必要中间层,完全符合Windows PE版本信息的标准结构。
  • 编码处理:针对pefile返回的字节串,优先用UTF-16LE解码(Windows版本资源的标准编码),解码失败时回退到系统默认的MBCS编码,避免出现乱码。
  • 返回完整字典:一次性返回所有版本信息字段,方便你按需提取需要的属性。

额外说明:关于「文件类型」的获取

你提到的「详细信息」选项卡中的「类型」(比如Notepad.exe显示为「应用程序」),这个信息并不在StringTable里,而是需要从PE头的Subsystem字段判断:

def get_pe_file_type(pe_path: str) -> Optional[str]:
    try:
        pe = PE(pe_path)
    except Exception as e:
        print(f"解析PE文件失败: {e}")
        return None

    subsystem_map = {
        1: "原生应用程序(不使用Windows子系统)",
        2: "GUI应用程序",
        3: "控制台应用程序",
        5: "OS/2应用程序",
        7: "POSIX应用程序",
        8: "Windows CE应用程序",
        9: "EFI应用程序",
        10: "EFI驱动程序",
        11: "EFI ROM镜像",
        12: "Xbox应用程序"
    }
    return subsystem_map.get(pe.OPTIONAL_HEADER.Subsystem, "未知类型")

调用这个函数就能得到对应文件的类型描述,和Windows属性窗口里的「类型」完全一致。

内容的提问来源于stack exchange,提问作者Larytet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:49:10