WPF(.NetFramework4.6)按钮绑定ICommand间歇性触发System.IO.FileLoadException求助
这个问题我之前处理过好几次,本质上是程序集绑定重定向的问题,再加上.NET Framework和.NET Standard/.NET Core组件之间的兼容性冲突,才导致了这种间歇性触发的异常。下面一步步带你排查和解决:
一、先搞清楚问题根源
错误提示里的System.Runtime, Version=4.2.0.0是.NET Core/.NET Standard体系里的版本,而你的目标框架是.NET Framework 4.6,它自带的System.Runtime版本要低得多(大概是4.0.0.0左右)。之所以是间歇性出现,通常有两个原因:
- 你引用的某些第三方NuGet包依赖了.NET Standard版本的System.Runtime,应用启动时的程序集加载上下文偶尔会优先加载这个高版本,和框架自带的版本撞车
- 按钮绑定的ICommand执行时,可能触发了某个延迟加载的组件,只有这个组件加载时才会去调用冲突的程序集,所以不是每次点击都会触发
二、排查步骤
- 检查NuGet依赖:打开你的
packages.config或者项目文件(.csproj),看看有没有引用依赖.NET Standard的包——比如新版本的Newtonsoft.Json、Prism、MVVM Light这类常用库,它们很可能偷偷引入了高版本的System.Runtime - 查看程序集绑定日志:打开VS的开发者命令提示符,运行
fuslogvw.exe(程序集绑定日志查看器),启用“记录所有绑定失败”,然后复现错误。通过日志能精准定位到到底是哪个组件在尝试加载System.Runtime 4.2.0.0,揪出问题源头 - 检查app.config的重定向配置:看看你的app.config里有没有关于System.Runtime的绑定重定向,如果没有或者配置不对,版本不匹配的问题就容易找上门
三、靠谱的解决办法
1. 添加正确的程序集绑定重定向
在app.config的<runtime>节点下添加以下配置,强制所有对System.Runtime的引用都重定向到.NET Framework兼容的版本:
<dependentAssembly> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" /> </dependentAssembly>
如果嫌手动写麻烦,也可以右键项目→属性→应用程序→勾选“自动生成绑定重定向”,VS会自动帮你生成正确的重定向配置。
2. 降级冲突的NuGet包
如果排查到某个第三方包是罪魁祸首,比如某个版本过高的MVVM库,可以尝试降级到兼容.NET Framework 4.6的稳定版本。举个例子,Newtonsoft.Json降到12.0.3版本就很稳妥——这个版本对.NET Framework 4.6的兼容性更好,不会强制引入高版本的System.Runtime。
3. 清理项目缓存
有时候项目的bin/obj目录里残留了旧版本的程序集,导致加载混乱。可以这么做:
- 删除项目的bin和obj文件夹
- 清理NuGet缓存:在VS里点击工具→NuGet包管理器→包管理器设置→清除所有NuGet缓存
- 重新生成解决方案
4. 检查.NET Framework安装情况
确保你的开发机器和部署机器上都安装了.NET Framework 4.6的最新更新(比如4.6.2),有时候系统自带的.NET Framework组件缺失更新也会导致这类加载问题。
四、验证解决效果
做完上面的步骤后,多点击几次按钮测试,同时可以用fuslogvw.exe确认没有再出现System.Runtime的绑定失败日志,这样就能彻底解决这个间歇性异常了。
内容的提问来源于stack exchange,提问作者developer7788

