.NET Core SCD应用为何不探查同目录程序集?如何解决?
为什么.NET Runtime不搜索当前目录程序集?怎么让它识别入口旁的DLL?
我之前也碰到过类似的部署坑,结合.NET Core的程序集加载机制,咱们来拆解原因和解决办法:
先搞清楚为什么会出现服务器差异
你已经设置了<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>,理论上所有依赖DLL都该被复制到输出目录,但出现这种不一致的可能原因有这几个:
- 两台服务器的.NET Core Runtime版本不匹配:高版本Runtime的加载逻辑和低版本有细微差异,可能优先遵循
dep.json指定的runtimes目录路径,而非当前目录 - 部署文件不完整:比如压缩解压、FTP传输时漏掉了部分DLL,或者某些带架构后缀的DLL只被复制到了runtimes子目录,没出现在根目录
dep.json的优先级规则:默认情况下,Runtime会优先按照dep.json里配置的路径查找程序集,哪怕当前目录有同名文件
解决方案(按优先级尝试):
1. 先确认部署文件的完整性
- 对比两台服务器的输出目录,把正常服务器上的所有文件(包括根目录DLL、runtimes子目录)完整复制到异常服务器,覆盖现有文件后再测试
- 重点检查报错里缺失的程序集是否真的在当前目录存在,有些NuGet包会针对性地把DLL放到runtimes目录,这时候可以手动把对应DLL移到根目录测试
2. 强制Runtime优先搜索当前目录
你可以修改runtimeconfig.json调整程序集搜索路径的优先级,把当前目录(.)加到additionalProbingPaths的最前面:
{ "runtimeOptions": { "additionalProbingPaths": [ ".", "./runtimes/win/lib/netstandard2.0" ], // 保留原有其他配置,比如framework、rollForward等 } }
这样Runtime会先在应用根目录查找所需程序集,找不到再去runtimes目录搜索。
3. 检查服务器的.NET Core Runtime版本
- 在两台服务器上分别运行
dotnet --info,确认都安装了netcoreapp2.0对应的Runtime版本(注意是Runtime,不是SDK) - 如果异常服务器没装对应版本,哪怕安装了托管包,也可能出现加载异常,建议重新安装匹配的Runtime
4. 改用自包含部署彻底解决依赖问题
如果上面的方法都没效果,推荐把应用部署成自包含模式,这样会把所有依赖的Runtime和DLL都打包到输出目录,完全不依赖服务器上的.NET Core环境:
修改你的项目文件(.csproj):
<PropertyGroup> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <RuntimeIdentifier>win-x64</RuntimeIdentifier> <!-- 服务器是32位就用win-x86 --> <SelfContained>true</SelfContained> </PropertyGroup>
然后执行dotnet publish -c Debug,把生成的bin\Debug\netcoreapp2.0\win-x64目录部署到服务器,直接运行里面的exe文件即可,不需要安装托管包。
额外注意:权限问题
有时候“找不到程序集”的错误其实是权限问题,要确保应用进程有读取当前目录所有文件的权限,比如IIS应用池的身份、或者运行exe的用户权限。
内容的提问来源于stack exchange,提问作者mohammad rostami siahgeli
相关产品推荐
相关产品推荐

