.NET Core 发布的应用程序失败并出现 FileNotFoundException

Posted

技术标签:

【中文标题】.NET Core 发布的应用程序失败并出现 FileNotFoundException【英文标题】:.NET Core published app fails with FileNotFoundException 【发布时间】:2018-11-22 00:38:28 【问题描述】:

我有一个目标为 netcoreapp2.1 的 .NET Core 控制台应用程序。它使用 Windows 兼容包调用现有的 WCF 服务。

当我通过 Visual Studio 运行它时,或者如果我使用 dotnet run 从命令行运行它,它工作正常。

但是,我想将其发布为 .exe 文件,以便我可以通过双击它来运行它。

所以,我运行了似乎成功的 Publish,但是当我尝试运行已发布的 .exe 文件时,它失败并出现以下异常:

System.IO.FileNotFoundException: Could not load file or assembly 
'System.Private.ServiceModel, Version=4.1.2.1, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.

这个错误发生在我运行发布的机器上,如果我尝试将发布的文件夹复制到另一台机器上。我相信System.Private.ServiceModelMicrosoft.Windows.Compatibility 包的某种深度依赖,但为什么这不起作用?确定应该自动复制到输出文件夹吗?

是否需要额外的配置或设置才能让发布自动引入依赖项?

如果重要的话,csproj 文件中的引用如下所示:

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.1" />
  </ItemGroup>

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,我通过安装 System.Private.ServiceModel 包从 nuget 手动添加了丢失的文件。

Link on nuget.org.

虽然这是一个 hack,因为从包的描述中你可以看到它是为 .Net 内部使用而设计的,但我没有找到任何其他选项。

【讨论】:

是的,它可以工作 - 但它让我担心其他程序集可能被遗漏,然后可能导致应用程序中的运行时错误。我在这里向 dotnet 团队提出了这个问题:github.com/dotnet/cli/issues/10381 这不起作用。运行 Newtonsoft.Json 依赖项时,我遇到了同样的问题。不知何故,dotnet publish 不会产生正确的输出来运行,即使将 nuget 依赖项显式添加到主项目并且看到依赖项 dll 确实存在时也是如此。见***.com/q/69408758/2948212【参考方案2】:

查看相关的 GitHub 问题*,人们似乎对建议的解决方法有不同的看法。

对我有用的是在构建后将 DLL 从运行时文件夹复制到 bin 文件夹,方法是将其添加到我的 Azure Function 应用程序 csproj:

<!-- https://github.com/dotnet/wcf/issues/2824 -->
<Target Name="FixForDotnetWcfIssueBuild" BeforeTargets="PostBuildEvent">
  <Copy SourceFiles="$(OutputPath)bin\runtimes\win\lib\netstandard2.0\System.Private.ServiceModel.dll" DestinationFolder="$(OutputPath)bin" />
</Target>
<Target Name="FixForDotnetWcfIssuePublish" AfterTargets="AfterPublish">
  <Copy SourceFiles="$(PublishDir)bin\runtimes\win\lib\netstandard2.0\System.Private.ServiceModel.dll" DestinationFolder="$(PublishDir)bin" />
</Target>

其他解决方法包括直接安装 System.Private.ServiceModel 包,或将 System.ServiceModel 的版本增加到 4.5.3,这两种方法都不适合我。

*

https://github.com/dotnet/wcf/issues/2824

https://github.com/Azure/azure-functions-host/issues/4304

https://github.com/Azure/azure-functions-host/issues/3568#issuecomment-433146109

https://github.com/dotnet/wcf/issues/2349

【讨论】:

【参考方案3】:

在 vsstudio nuget 包中添加 Install-Package System.Private.ServiceModel

现在,当您发布 dll 时将被包含在内。

【讨论】:

【参考方案4】:

我发现这是由我的一个包中的PrivateAssets="All" 引起的:

<PackageReference Include="ULabs.VBulletinEntity" Version="0.7.17" />

背景:ULabs.VBulletinEntity 本身是指一些共享库,应该自动发送而不安装第二个包。于是我尝试了this workaround,推荐PrivateAssets="All"集成共享库。

这可行,但是在部署到 Linux 时,dotnet restore 之后的包不存在。这会在启动应用程序后导致 FileNotFound 异常。由于我没有收到任何错误,我尝试使用手动安装它

RUN dotnet add package ULabs.VBulletinEntity --version -s my-baget-repo

这至少给了我一个错误:

error: Package 'ULabs.VBulletinEntity' is incompatible with 'all' frameworks in project '/app/MyApp/MyApp.csproj'.

错误消息没有任何有用的信息。大多数情况下,他们使用另一个版本(例如 3.0 项目中的 .NET Core 2.0 库)。在另一种情况下,它似乎是某种有线错误。

删除PrivateAssets="All" 后,包出现在发布输出中,我可以再次启动应用程序。这对我来说似乎很奇怪,但也许这同一个人时间。我在这个问题上浪费了几个小时。使用 .NET Core 2.1 和 .NET Standard 2.0 作为库。

【讨论】:

以上是关于.NET Core 发布的应用程序失败并出现 FileNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章

使用 .Net Core 在 linux 机器上查找内核数失败并出现错误(未终止的引用字符串)

包还原失败/.Net Core 安装错误

IIS 应用程序池登录凭据停止 .net Core

在管道中发布 NET 6 应用程序失败并出现“找不到类型”异常

.NET Core 2.2 - “HTTP 错误 500.30 - ANCM 进程内启动失败”

控制器无法识别 JWT 角色.net core 5