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

CodeDom编译EXE嵌入资源调用报ArgumentNullException问题咨询

问题根因

你遇到的ArgumentNullException是因为Assembly.GetManifestResourceStream()返回了null,空流传入BinaryReader触发参数校验报错。核心原因是嵌入资源的实际逻辑名和你拼接的查找名不匹配:

  • 你用Parameters.EmbeddedResources.Add("C:/Users/User1/Music/sample.mp3");写法本身语法合法,但C#编译器处理嵌入资源时,如果没有显式指定逻辑名,会按照编译器默认规则生成资源名,和你假设的命名空间.文件名规则不一致,导致查找失败。
  • 你之前遇到的Properties does not exist in the current context报错属于正常情况:Properties.Resources是Visual Studio给常规项目自动生成的包装类,CodeDom动态编译场景下默认不会生成这个类,你放弃该方案的选择是对的。
修复方案

方案1:显式指定资源逻辑名(推荐)

CompilerParameters.EmbeddedResources.Add支持第二个参数自定义资源逻辑名,直接和你查找用的命名规则对齐即可:

// 如果你调用Extract时不传InternalPath,就指定逻辑名为TestCompiler.Music.mp3
Parameters.EmbeddedResources.Add(@"C:\Users\User1\Music\sample.mp3", "TestCompiler.Music.mp3");

// 如果你要带Resources前缀,就指定逻辑名为TestCompiler.Resources.Music.mp3
// Parameters.EmbeddedResources.Add(@"C:\Users\User1\Music\sample.mp3", "TestCompiler.Resources.Music.mp3");

该方案完全避开默认命名规则的坑,后续查找资源时不会出现匹配问题。

方案2:修正Extract方法,增加校验和调试逻辑

修改方法增加空校验,找不到资源时直接输出当前程序集所有嵌入资源名,不用手动猜规则:

private static void Extract(string NameSpace, string OutputDir, string InternalPath, string ResourceName)
{
    string resourceFullName = NameSpace + "." + (string.IsNullOrEmpty(InternalPath) ? "" : InternalPath + ".") + ResourceName;
    Assembly assembly = Assembly.GetCallingAssembly();
    
    // 资源不存在时输出所有已嵌入的资源名,方便调试
    if (assembly.GetManifestResourceInfo(resourceFullName) == null)
    {
        string allEmbeddedResources = string.Join("\n", assembly.GetManifestResourceNames());
        throw new InvalidOperationException($"未找到目标资源:{resourceFullName}\n当前程序集已嵌入的所有资源:\n{allEmbeddedResources}");
    }

    using (Stream s = assembly.GetManifestResourceStream(resourceFullName))
    using (BinaryReader r = new BinaryReader(s))
    // 用Path.Combine拼接路径,避免斜杠错误
    using (FileStream fs = new FileStream(Path.Combine(OutputDir, ResourceName), FileMode.OpenOrCreate))
    using (BinaryWriter w = new BinaryWriter(fs))
    {
        w.Write(r.ReadBytes((int)s.Length));
    }
}

如果你不想显式指定逻辑名,运行修改后的方法,从报错信息里复制实际生成的资源名,替换调用Extract时的参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:27:05