.NET 6中移动所有DLL至独立文件夹后程序无法启动问题排查
问题原因及解决办法
核心问题点
.NET 6不支持App.config里的<probing>配置
你用的<probing privatePath="DLLs">是传统.NET Framework的程序集加载配置,.NET 6(以及.NET 5之后的统一平台版本)已经抛弃了这套逻辑,不会读取App.config中的assemblyBinding节点,所以你加的路径配置完全不起作用,程序启动时找不到移到DLLs文件夹里的依赖组件。Post-build命令误移关键文件
你的move /Y "$(TargetDir)\*.dll"会把输出目录下所有DLL都移走,包括.NET 6运行时相关的核心组件(如果是框架依赖部署模式),或者主程序必须的基础依赖库,直接导致程序启动失败,触发错误代码0x8000809a(本质是程序集加载失败)。
可行的解决方案
方案1:直接让依赖项目输出到DLLs文件夹
不需要Post-build移动操作,给每个自建的引用项目修改.csproj配置,让它们编译后直接输出到主项目的DLLs目录:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <!-- 替换成你的主项目输出路径,比如主项目叫MyProg --> <OutputPath>..\MyProg\bin\$(Configuration)\$(TargetFramework)\DLLs</OutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> </PropertyGroup> </Project>
主项目保持默认输出路径即可,编译时依赖DLL会自动生成到DLLs文件夹,无需后续移动。
方案2:自定义程序集加载逻辑
如果必须保留Post-build移动步骤,就在主程序的Program.cs开头添加自定义程序集解析代码,让程序主动去DLLs文件夹找依赖:
using System.Reflection; using System.Runtime.Loader; using System.IO; // 注册程序集解析回调 AssemblyLoadContext.Default.Resolving += (context, assemblyName) => { var dllFilePath = Path.Combine(AppContext.BaseDirectory, "DLLs", $"{assemblyName.Name}.dll"); if (File.Exists(dllFilePath)) { return context.LoadFromAssemblyPath(dllFilePath); } return null; };
补充优化:精准移动DLL
修改Post-build命令,只移动你自己的自建项目DLL,避免误移运行时核心文件:
mkdir "$(TargetDir)DLLs" # 替换成你的自建库文件名 move /Y "$(TargetDir)\MyCustomLibA.dll" "$(TargetDir)DLLs\" move /Y "$(TargetDir)\MyCustomLibA.pdb" "$(TargetDir)DLLs\" move /Y "$(TargetDir)\MyCustomLibB.dll" "$(TargetDir)DLLs\" move /Y "$(TargetDir)\MyCustomLibB.pdb" "$(TargetDir)DLLs\"
内容的提问来源于stack exchange,提问作者Thern
相关产品推荐
相关产品推荐

