Как настроить однофайловое приложение .Net Core 3.0 Web API для поиска appsettings.json
файла, находящегося в том же каталоге, в котором построено однофайловое приложение?
После запуска
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
Каталог выглядит так:
XX/XX/XXXX XX:XX PM <DIR> .
XX/XX/XXXX XX:XX PM <DIR> ..
XX/XX/XXXX XX:XX PM 134 appsettings.json
XX/XX/XXXX XX:XX PM 92,899,983 APPNAME.exe
XX/XX/XXXX XX:XX PM 541 web.config
3 File(s) 92,900,658 bytes
Тем не менее, попытка запустить APPNAME.exe
приводит к следующей ошибке
An exception occurred, System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\Users\USERNAME\AppData\Local\Temp\.net\APPNAME\kyl3yc02.5zs\appsettings.json'.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
...
Я пытался найти решения по схожему, но отдельному вопросу , а также по другим вопросам переполнения стека.
Я попытался передать следующее SetBasePath()
Directory.GetCurrentDirectory()
environment.ContentRootPath
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
Каждый приводил к одной и той же ошибке.
Корень проблемы в том, что PublishSingleFile
двоичный файл разархивирован и запускается из temp
каталога.
В случае этого единственного файлового приложения местоположение, которое это искало, appsettings.json
было следующим каталогом:
C:\Users\USERNAME\AppData\Local\Temp\.net\APPNAME\kyl3yc02.5zs
Все вышеперечисленные методы указывают на место разархивирования файла, которое отличается от места, из которого он был запущен.
источник
Если у вас все в порядке с использованием файлов во время выполнения вне исполняемого файла, тогда вы можете просто пометить файлы, которые вы хотите, за пределами, в csproj. Этот метод допускает живые изменения и тому подобное в известном месте.
Если это неприемлемо и должно иметь ТОЛЬКО один файл, я передаю путь, извлеченный из одного файла, как корневой путь в моей настройке хоста. Это позволяет конфигурации и бритве (которую я добавляю после) найти файлы как обычно.
Обратите внимание, что для создания единого файла без использования PDB вам также потребуется:
источник
Мое приложение работает на .NET Core 3.1, публикуется в виде одного файла и запускается как служба Windows (что может повлиять или не повлиять на проблему).
Предложенное решение с
Process.GetCurrentProcess().MainModule.FileName
корнем контента работает для меня, но только если я установил корень контента в нужном месте:Это работает:
Это не работает:
источник