`未处理的异常:System.ArgumentNullException:值不能为空。` 使用启动脚本 运行ning `dotnet 运行` 时出错

`Unhandled Exception: System.ArgumentNullException: Value cannot be null.` error while running `dotnet run` using a startup script

我正在尝试 运行 在系统服务器 Startup/Reboot 上使用 dotnet run --configuration Release 的 dotnet 应用程序。我正在使用 init.d 脚本来实现相同的目的。

我的启动脚本位于 /etc/init.d/myscript 包含以下内容:

#!/bin/sh
/home/user/myscripts/botScript.sh

botScript.sh 的内容:

#!/bin/bash
cd /home/user/bot/
nohup dotnet run --configuration Release &

当我的服务器启动或重新启动时,启动脚本得到执行,但 dotnet run 不起作用。我收到以下错误:

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: path1
   at System.IO.Path.Combine(String path1, String path2, String path3)
   at Microsoft.DotNet.ProjectModel.Resolution.PackageDependencyProvider.ResolvePackagesPath(String rootDirectory, GlobalSettings settings)
   at Microsoft.DotNet.Configurer.NuGetCacheSentinel.get_NuGetCachePath()
   at Microsoft.DotNet.Configurer.NuGetCacheSentinel.Exists()
   at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.ShouldPrimeNugetCache()
   at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.Configure()
   at Microsoft.DotNet.Cli.Program.ConfigureDotNetForFirstTimeUse(INuGetCacheSentinel nugetCacheSentinel)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)

但是所有其他命令在该脚本中都可以正常工作,甚至只是 运行ning dotnet 也可以正常工作(我已经检查过了)。只是dotnet run不行。

是的,但是当我 运行 脚本时,myscriptbotScript.sh,在登录到我的服务器后,它工作正常,没有任何错误。

拜托,有人可以帮我解决这个问题吗?

PackageDependencyResolver 中显然存在错误,但要找到解决方法,请考虑找到 packages 文件夹的顺序:

  1. global.json { "packages": "..." }
  2. NUGET_PACKAGES 环境变量。
  3. {DefaultLocalRuntimeHomeDir}\packages

您的代码一直下降到上面的案例 #3。要解决此问题,请创建一个名为 NUGET_PACKAGES 的环境变量,指向您的 packages 文件夹。例如,在 botScript.sh:

#!/bin/bash
cd /home/user/bot/
export NUGET_PACKAGES="/home/user/.nuget/packages" # <=== 
nohup dotnet run --configuration Release &

有关详细信息,请参阅 PackageDependencyResolver.cs and PackageDependencyResolver.cs

不要 运行 使用 root 用户的 dotnet

如果它 运行 来自 init.d,它是用 root 用户调用的。 运行具有 root 的 ning 程序会使您的计算机面临严重的安全问题,尤其是 .net 核心仍在大力开发中 not 安全强化。

运行 具有特定用户的服务

您的错误可能是由于 root 没有定义包目录,但是当您手动 运行 它时,它与您的 user 一起 /home/user/.nuget/packages 目录已定义。

  • asp.net core documentation 开始,您可以设置服务并指定将 运行 dotnet
  • 的用户
  • 只需使用su命令与指定用户运行 dotnet

主管用户

这里是我自己站点的 supervisor conf 的摘录

/etc/supervisor/conf.d/mysite.conf:

[program:mysite]
command=/usr/bin/dotnet /var/www/mysite/MySite.dll
directory=/var/www/mysite
autostart=true
autorestart=true
stderr_logfile=/var/log/mysite.err.log
stdout_logfile=/var/log/mysite.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data <=== SPECIFY A USER HERE
stopsignal=INT

不要在 development/debugging 目的之外使用 dotnet run

正如dotnet --help所说,运行命令编译并执行一个项目。

run           Compiles and immediately executes a .NET project

编译需要额外的步骤,然后是计算能力等额外的时间(每次都是运行,即使代码没有变化)。它还需要恢复和构建才能工作(这需要普通的开发人员用户)。由于可能会失败的额外步骤,它也更容易失败。

相反 运行 与您的开发人员用户一起编译一次,然后 运行 您的程序与 www-data 等服务用户(这是网站的一种内置用户)

dotnet MyCompiledAssembly.dll