使用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
问题分析与解决方案
问题根源
- 直接覆盖原主程序集:ILRepack配置中
OutputAssembly与MainAssembly同名,合并时直接覆盖原exe文件,导致Win32资源读取/写入时出现异常,触发空引用。 - 旧版本组件bug:ILRepack.MSBuild.Task 2.0.13存在Win32资源处理的已知bug,尤其在带
RuntimeIdentifier的.NET Framework项目中更容易触发。 - 输入集不完整:
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
相关产品推荐
相关产品推荐

