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

使用ILRepack.MSBuild.Task触发空引用异常,求问题排查

问题描述

现有.NET Framework 4.6项目,尝试使用ILRepack.MSBuild.Task(版本2.0.13)合并程序集生成单文件可执行文件,项目配置及代码如下:

TestILRepack.csproj

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net46</TargetFramework>
        <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="CommandLineParser" Version="2.9.1" />
        <PackageReference Include="ILRepack.MSBuild.Task" Version="2.0.13" />
    </ItemGroup>

    <Target Name="ILRepack" BeforeTargets="PostBuildEvent" >
        <ILRepack Verbose="true" OutputType="$(OutputType)" MainAssembly="$(AssemblyName).exe" OutputAssembly="$(AssemblyName).exe" InputAssemblies="$(OutDir)\*.dll" WilcardInputAssemblies="true" WorkingDirectory="$(OutDir)" />
    </Target>

</Project>

Program.cs

using CommandLine;
using System;

namespace CoolTool
{
  public class Program
  {
    public class Options
    {
      [Option('v', "verbose", Required = false, HelpText = "(Type: switch). Option to display detailed log.")]
      public bool Verbose { get; set; }
    }

    public static void Main(string[] args)
    {
      var parser = new Parser
      (
        settings =>
        {
          settings.CaseSensitive = false;
          settings.AutoHelp = true;
          settings.HelpWriter = Parser.Default.Settings.HelpWriter;
        }
      );

      parser.ParseArguments<Options>(args).WithParsed
      (
        options =>
        {
          if (options.Verbose)
          {
            Console.WriteLine("Verbose");
          }
          else
          {
            Console.WriteLine("Silent");
          }

          if (args.Length == 0)
          {
            Console.WriteLine("No arguments specified. Try '--help' command.");
          }
        }
      )
      .WithNotParsed(options => { });
    }
  }
}

在VS Enterprise 2022(64位,版本17.7.5)编译时触发空引用异常:

Error       Object reference not set to an instance of an object.
at ILRepacking.Steps.Win32Resources.PE.ImageWriter.CopySection(Section from, Section to)
at ILRepacking.Steps.Win32Resources.Win32ResourceStep.Patch(String outFile)
at ILRepacking.ILRepack.Repack()
at ILRepack.MSBuild.Task.ILRepack.Execute() TestILRepack    C:\Users\hakan.olsson\Desktop\TestILRepack\TestILRepack.csproj 19
问题分析与解决方案

问题根源

  1. 直接覆盖原主程序集:ILRepack配置中OutputAssembly与MainAssembly同名,合并时直接覆盖原exe文件,导致Win32资源读取/写入时出现异常,触发空引用。
  2. 旧版本组件bug:ILRepack.MSBuild.Task 2.0.13存在Win32资源处理的已知bug,尤其在带RuntimeIdentifier的.NET Framework项目中更容易触发。
  3. 输入集不完整:InputAssemblies仅指定dll文件,未明确包含主exe,虽然启用了通配符,但逻辑上可能导致合并流程异常。

解决步骤

1. 更新ILRepack.MSBuild.Task版本

将组件版本升级到最新稳定版(如2.0.17),修复已知的Win32资源处理空引用问题:

<PackageReference Include="ILRepack.MSBuild.Task" Version="2.0.17" />

2. 修改ILRepack任务配置

避免直接覆盖原程序集,优化输入集并排除不必要的系统程序集,修改后的Target配置如下:

<Target Name="ILRepack" BeforeTargets="PostBuildEvent">
    <ILRepack 
        Verbose="true" 
        OutputType="$(OutputType)" 
        MainAssembly="$(AssemblyName).exe" 
        OutputAssembly="$(AssemblyName)_merged.exe" 
        InputAssemblies="$(OutDir)\$(AssemblyName).exe;$(OutDir)\*.dll" 
        WilcardInputAssemblies="true" 
        WorkingDirectory="$(OutDir)"
        ExcludeAssemblies="System*,Microsoft*"
        <!-- 若仍报错,可尝试关闭Win32资源合并:NoWin32Resources="true" -->
    />
    <!-- 替换原文件并清理冗余dll -->
    <Delete Files="$(OutDir)\$(AssemblyName).exe" />
    <Move SourceFiles="$(OutDir)\$(AssemblyName)_merged.exe" DestinationFiles="$(OutDir)\$(AssemblyName).exe" />
    <Delete Files="$(OutDir)\*.dll" />
</Target>

3. 可选:调整RuntimeIdentifier设置

如果项目不需要特定平台的编译输出,可以移除<RuntimeIdentifier>win-x64</RuntimeIdentifier>,使用默认的AnyCPU配置,减少平台相关的资源处理冲突。

验证

重新编译项目后,输出目录将生成单个可执行文件,运行该文件可正常处理命令行参数,无合并相关异常。

内容的提问来源于stack exchange,提问作者Håkan Olsson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:17:27