WPF迁移.NET6后Windows Server环境System.Runtime加载失败问题排查
问题背景
WPF项目从.NET Framework迁移至.NET 6后,本地Windows 11构建正常,但Azure Pipeline及Windows Server 2022虚拟机上构建失败,错误信息如下:
Error LC0000 'Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)' ProAnalysisUI C:\...\ProAnalysisUI\LC 1
原疑问
- 错误提示缺失
System.Runtime程序集,但项目未直接引用,仅依赖包HIC.System.Windows.Forms.DataVisualization包含该兼容.NET 6的程序集,如何追踪错误根源? - 错误显示发生在
LC文件中,但文件结构无此文件,LC是什么? - 为何本地Windows 11无此错误?
定位更新
经测试锁定第三方工具Actipro:
- 采用「安装软件后引用本地程序集」方式时,构建运行正常;
- 迁移至Azure后切换为「使用NuGet包」方式,本地正常但Pipeline/虚拟机上失败;
- 卸载本地Actipro安装后,本地也出现相同错误,确认问题与虚拟机环境无关。
补充疑问:Actipro的NuGet包是否会从本地存储读取许可证信息?
解答
1. 错误根源追踪
项目未直接引用System.Runtime,但Actipro NuGet包可能在构建阶段(如许可证验证、组件初始化)尝试加载该程序集的引用版本而非运行时版本。排查方式:
- 在Azure Pipeline中添加MSBuild参数
/verbosity:detailed,启用详细日志,查看LC任务执行时的依赖加载链,定位触发错误的组件; - 检查项目
PackageReference配置,确保所有依赖包(含Actipro)版本完全兼容.NET 6,避免混合引用.NET Framework与.NET 6程序集; - 执行
dotnet list package --vulnerable命令,检查依赖包兼容性问题。
2. 「LC」的含义
LC是**License Compiler(许可证编译器)**的缩写,是MSBuild内置任务,用于处理项目中的.licx许可证文件。当项目包含需许可证验证的组件(如Actipro)时,MSBuild自动调用LC任务加载相关程序集验证许可证,若加载了错误版本的程序集(如引用版本而非运行时版本),则触发该错误。
3. 本地Windows 11无错误的原因
本地安装Actipro软件后,系统中存在组件的运行时程序集及许可证信息,LC任务优先加载本地安装路径下的兼容程序集,而非NuGet包中的引用程序集。卸载本地Actipro后,LC任务只能使用NuGet包中的程序集,此时暴露程序集加载兼容性问题,与Pipeline/虚拟机环境一致。
Actipro NuGet包的许可证读取逻辑
根据Actipro官方许可证指南翻译内容:
Actipro WPF组件的许可证验证规则:
- 开发环境中,安装版的许可证信息存储在注册表;NuGet包版需依赖项目根目录的
ActiproLicense.lic文件; - NuGet包版本不会自动读取本地安装的许可证信息,必须手动配置:
- 将
ActiproLicense.lic文件添加至项目根目录; - 在项目文件中添加配置,确保文件复制到输出目录:
<ItemGroup> <None Include="ActiproLicense.lic"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> - 确认许可证文件密钥与授权信息匹配,且适用于.NET 6环境。
- 将
若Azure Pipeline或虚拟机中缺少ActiproLicense.lic文件,或许可证密钥不兼容,LC任务验证时会加载错误程序集,进而触发System.Runtime加载错误。
内容的提问来源于stack exchange,提问作者zhangjinzhou

