Публикация отдельного exe-файла в .Net Core 3.0 и использование app.config - PullRequest
2 голосов
/ 17 октября 2019

У меня есть проект .Net Core 3.0, и я хотел воспользоваться новой опцией публикации проекта в виде одного файла .exe.

Я использую командуdotnet publish -r win-x64 -c Release /p:PublishSingleFile=true

Это, безусловно, создает один файл .exe, но проблема в том, что у меня есть файл app.config в моем проекте, который пользователи должны изменить, и я не уверен, будет ли он упакован в.exe, а также. Когда я тестировал созданный .exe, он считывает значения, которые я изначально поместил в app.config.

Я попытался установить для параметра «Копировать в выходной каталог» значение «Копировать всегда», но это не изменилось. что-нибудь. Для параметра «Действие сборки» задано значение «Нет».

Как настроить его таким образом, чтобы все, кроме файла app.config, упаковывалось в этот файл .exe, чтобы пользователь мог изменять значения?

Ответы [ 2 ]

2 голосов
/ 17 октября 2019

Короткая версия

.NET Core не использует app.config, вам придется обновить систему до новой конфигурации или вручную управлять файлами,

  1. Добавьте <ExcludeFromSingleFile>true</ExcludeFromSingleFile> к файлу App1.config, чтобы он не попал в пакет.
  2. Вручную добавьте файл MyApp.exe.config с настройками производства и добавьте <CopyToPublishDirectory>Always</CopyToPublishDirectory>, чтобы опубликовать его в каталоге Publish. Преобразования не запустятся, поэтому убедитесь, что в них есть все, что нужно.
  3. Наконец, явно загрузите файл, чтобы избежать ошибки в базовом разрешении пути приложения
var hostFile=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
ConfigurationManager.OpenExeConfiguration(hostFile+".config");

Загрузкаопубликованный файл, как если бы это был любой другой файл


.NET Core 3, даже для Windows Forms, не использует app.config. Система конфигурации .NET Core описана в Конфигурация в ASP.NET Core и, несмотря на название, применима ко всем приложениям .NET Core. Он также гораздо более мощный, загружая конфигурацию из нескольких источников, включая файлы (даже INI), базы данных, хранилища настроек Azure или AWS и т. Д.

Добавление Application Configuration File в новый проект Windows Forms, оба в VS 2019и командная строка создает файл App1.config без особого значения для VS или .NET Core. Создание AppName.exe.config требует фактического создания нового файла AppName.exe.config с производственными настройками.

Единственный способ прочитать файл .config старого стиля - это явная загрузка его с помощью ConfigurationManager.OpenExeConfiguration. Это просто загружает файл и анализирует его. Можно передать любой путь к файлу или указать ConfigurationUserLevel, который просто разрешается в местоположение файла на основе базового каталога исполняемого файла.

И вот тут начинается беда. Есть ошибка.

При использовании однофайловых исполняемых файлов все файлы объединяются в один файл хоста с расширением .exe. Когда этот файл запускается в первый раз, он распаковывает свое содержимое в AppData\Local\Temp\.net\, в новую папку, названную для приложения. По проекту , базовый каталог приложения должен быть путь хоста , где находится единственный .exe. К сожалению, есть ошибка , и в базовом каталоге остается местоположение пакета и .dll, который фактически выполняется хостом.

Вот почему

System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None).FilePath 

возвращает C:\Users\myUser~1\AppData\Local\Temp\.net\ConsoleApp_NetCore\nk5sdmz5.ym1\ConsoleApp_NetCore.dll.config, и я готов поспорить AppContext.BaseDirectory возвращает C:\Users\myUser~1\AppData\Local\Temp\.net\ConsoleApp_NetCore\nk5sdmz5.ym1\

Обходной путь , позволяющий получить путь к хосту и явно загрузить файл настроек. Это означает, что теперь мы можем использовать любое имя файла. Если мы сохраняем старое соглашение о присвоении имени файлу appname.exe.config, мы можем просто добавить .config к полному пути хоста:

var hostFile=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
ConfigurationManager.OpenExeConfiguration(hostFile+".config");

Это должно быть сделано также с поставщиком .NET Core File.

1 голос
/ 17 октября 2019

Вы должны пометить файл как <ExcludeFromSingleFile>true</ExcludeFromSingleFile> в настройках проекта.

https://github.com/dotnet/core-setup/issues/7738 https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md#build-system-interface

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...