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

.NET 9中如何将.res文件正确嵌入PE文件并生成指定资源结构?

问题原因

直接将.res文件的原始字节写入资源节是错误的,PE文件的.rsrc节需要符合特定的资源目录层级结构,当前写法只是把.res的二进制数据直接塞入,没有构建正确的资源目录表头,导致7-Zip无法识别资源层级,只能把整个.rsrc节当成单个文件。

解决方案

需要解析.res文件中的资源内容,构建符合PE规范的资源目录结构,再通过ResourceSectionBuilder序列化到程序集中。以下是修改后的VersionInfoBuilder实现:

using System.Resources;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Emit;

internal class VersionInfoBuilder : ResourceSectionBuilder
{
    private readonly ResourceDirectory _rootResourceDirectory;

    public VersionInfoBuilder(string resFilePath)
    {
        _rootResourceDirectory = new ResourceDirectory(0);
        if (string.IsNullOrWhiteSpace(resFilePath)) return;

        // 读取.res文件中的资源
        using var resStream = File.OpenRead(resFilePath);
        using var resReader = new ResourceReader(resStream);

        // 版本信息对应的资源类型ID(PE规范定义的RT_VERSION)
        const int ResourceType_Version = 16;
        // 创建版本信息类型的目录
        var versionTypeDir = new ResourceDirectory(ResourceType_Version);
        _rootResourceDirectory.Entries.Add(new ResourceDirectoryEntry(versionTypeDir));

        // 遍历.res中的资源项(版本信息通常仅一项)
        foreach (DictionaryEntry entry in resReader)
        {
            var resourceData = (byte[])entry.Value;
            
            // 创建名称目录(默认名称ID为1)
            var nameDir = new ResourceDirectory(1);
            versionTypeDir.Entries.Add(new ResourceDirectoryEntry(nameDir));

            // 创建语言目录(示例使用中文简体ID:2052,英文可改用1033)
            var langDir = new ResourceDirectory(2052);
            nameDir.Entries.Add(new ResourceDirectoryEntry(langDir));

            // 添加资源数据条目
            var dataEntry = new ResourceDataEntry(
                contentId: new BlobContentId(Guid.NewGuid()),
                data: resourceData,
                codePage: 0);
            langDir.Entries.Add(new ResourceDirectoryEntry(dataEntry));
        }
    }

    protected override void Serialize(BlobBuilder builder, SectionLocation location)
    {
        _rootResourceDirectory.Serialize(builder, location);
    }
}
说明
  • 代码通过ResourceReader解析.res文件内容,构建了PE资源要求的三层目录结构:资源类型目录→资源名称目录→语言目录,最终指向资源数据。
  • 版本信息对应的资源类型固定为RT_VERSION(ID=16),这是PE规范的标准定义。
  • 语言ID可按需修改,比如英文环境用1033,中文简体用2052。
  • 替换原有VersionInfoBuilder后重新生成程序集,7-Zip就能正确识别.rsrc为包含版本信息的文件夹结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:54:53