dsm*_*ith 8 .net c# migration .net-core
问题的简短版本:
.NET Core 3 中是否有任何方法可以使用与<probing>app.config 中的元素相同的规则来指定本地探测路径?additionalProbingPaths似乎不起作用。
问题的长版:
我正在将一个项目从 .NET Framework 迁移到 .NET Core 3。在原始项目中,我在 lib/ 文件夹中保留了许多辅助 dll。这很好用,因为我在 中设置了探测路径App.exe.config,如下所示:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib" />
</assemblyBinding>
</runtime>
Run Code Online (Sandbox Code Playgroud)
但是,将项目转换为 .NET Core 3 后,程序将无法运行,说找不到 dll。将App.exe.config仍然存在,并且仍在读/使用,因为它也包含了对System.Configuration参数信息,程序的一部分也可正常工作。
我已经确定有一个新的 json 文件存储程序的配置信息,在App.runtimeconfig.json. 它是自动生成的,默认情况下不包含其他探测路径,但App.runtimeconfig.dev.json文件包含一些。
现在,我无法使用 .dev.json 文件中的路径,因为这些路径指向本地用户目录,并且不能用于部署。但是,我可以通过使用runtimeconfig.template.json项目目录中的模板文件 ( )将我自己的版本添加到主 runtimeconfig中。这会将属性添加到runtimeOptions主 runtimeconfig 文件中的分组中。模板代码为:
{
"additionalProbingPaths": [
"lib"
]
}
Run Code Online (Sandbox Code Playgroud)
App.runtimeconfig.json文件的最终输出是:
{
"runtimeOptions": {
"tfm": "netcoreapp3.0",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "3.0.0-preview6-27804-01"
},
"additionalProbingPaths": [
"lib"
]
}
}
Run Code Online (Sandbox Code Playgroud)
然而,我插入的相对路径似乎根本没有被使用,无论是我使用模板将它插入到主 runtimeconfig 文件中,还是只是手动编辑 dev.json 文件。我还尝试了许多关于如何指定目录的变体。如果指定的程序集不在根程序目录中,程序总是会生成一个错误,指出未找到指定的程序集。该错误表示它正在寻找lib/netstandard2.0/HtmlAgilityPack.dll它从App.deps.json文件中获取的(或其他类似的库)。
解决方法是让所有库都位于根程序目录中,但由于这以前可以使用,我希望它现在可以使用,我想知道我做错了什么。尝试使用 Visual Studio 中的诊断输出获取更多信息失败,因为程序在生成任何诊断信息之前终止。
因此,根据从这个 Github issue获得的信息,我发现当前没有<probing>与app.exe.config.NET Core 中的元素等效的元素。因此,没有简单的“将所有这些 .dll 放入子目录并从那里工作”的解决方案。
但是,additionalProbingPaths如上所述,可以通过一些额外的调整来使用该指令。
首先,将additionalProbingPaths模板文件中的目录设置为“bin”之类的内容。这将定义新程序集存储位置的根,该位置将被构造为看起来像 NuGet 存储库。
然后在构建后事件中设置命令以将(例如)HtmlAgilityPack.dll文件移动到"$(TargetDir)bin/HtmlAgilityPack/1.11.8/lib/netstandard2.0". 完整路径由deps.json文件中提供的程序集信息的两半构成:"HtmlAgilityPack/1.11.8",并"lib/netstandard2.0/HtmlAgilityPack.dll"位于"runtime"小节下。然后,正常的依赖项解析过程将能够根据deps.json文件中的内容和bin探测路径找到它。
此外,复制为后期构建生成的命令,并在 .csproj 文件 ( <Target Name="PostPublish" AfterTargets="Publish">) 中创建另一个 Target 元素,使用$(PublishDir)代替$(TargetDir)来定义输出。这将使构建系统在发布和构建时执行相同的文件移动。
这确实意味着每次更新包版本号时都要更新文件移动命令,因此需要额外的手动工作来保持它最新。
我希望他们能够改进构建系统以自动执行此类操作,因为除了清理内容之外,它还为多个版本的依赖项打开了选项,并且可能有助于解决 .NET 中持续存在的版本控制问题。
附录:一种将各种 DLL 移动到可用目录中的更简洁的方法。使用构建后代码窗口是一种可怕的处理方式,但使用标准 MSBuild 命令处理起来要容易得多。但是,当包版本更改时,它仍然需要手动更新。
下面为构建和发布进行设置。请注意,这些必须单独设置。在不同的“父”操作中定义目标目录变量后,您不能重构以使用一组移动命令,因为发布隐式首先构建,并且给定的目标操作只能被调用一次。所以一旦在构建过程中被调用,在发布过程中就不能再次调用。
<Target Name="CreateBuildBin" AfterTargets="Build">
<MakeDir Directories="$(TargetDir)bin" Condition="!Exists('$(TargetDir)bin')" />
</Target>
<Target Name="MoveBuildDlls" AfterTargets="CreateBuildBin">
<Message Importance="high" Text="Build directory = $(TargetDir)" />
<Copy SourceFiles="$(SolutionDir)LICENSE.txt" DestinationFolder="$(TargetDir)" />
<Move SourceFiles="$(TargetDir)HtmlAgilityPack.dll" DestinationFolder="$(TargetDir)bin/HtmlAgilityPack/1.11.17/lib/netstandard2.0" />
</Target>
<Target Name="CreatePublishBin" AfterTargets="Publish">
<MakeDir Directories="$(PublishDir)bin" Condition="!Exists('$(PublishDir)bin')" />
</Target>
<Target Name="MovePublishDlls" AfterTargets="CreatePublishBin">
<Message Importance="high" Text="Publish directory = $(PublishDir)" />
<Copy SourceFiles="$(SolutionDir)LICENSE.txt" DestinationFolder="$(PublishDir)" />
<Move SourceFiles="$(PublishDir)HtmlAgilityPack.dll" DestinationFolder="$(PublishDir)bin/HtmlAgilityPack/1.11.17/lib/netstandard2.0" />
</Target>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3929 次 |
| 最近记录: |