Есть ли способ заставить консольное приложение работать, используя только один файл в.NET Core?

В.NET Framework вы можете сделать один .EXE файл, который будет запускаться из командной строки без каких-либо дополнительных файлов конфигурации (и если вы используете ILMerge, вы можете поместить все .DLL ссылки в 1 .EXE монтаж).

Я пытаюсь использовать.NET Core для достижения того же результата, но пока безуспешно. Даже самый простой Hello World приложение без зависимостей требует наличия файла с именем <MyApp>.runtimeconfig.json для того, чтобы запустить с помощью dotnet.exe,

dotnet F:\temp\MyApp.dll

Содержание <MyApp>.runtimeconfig.json являются следующими:

{
  "runtimeOptions": {
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "1.1.1"
    }
  }
}

Без этого файла конфигурации в той же папке, что и .DLL Я получаю следующую ошибку:

A fatal error was encountered. The library 'hostpolicy.dll' required to
execute the application was not found in 'F:\temp'.

Мой вопрос: есть ли какой-нибудь способ изменить приложение, чтобы он не требовал присутствия этого файла конфигурации, чтобы значения по умолчанию этой информации компилировались в .DLL но можно переопределить, добавив файл конфигурации?

ПРИМЕЧАНИЕ. Я также хочу убедиться, что он "просто работает" независимо от платформы, на которой он установлен, при условии, что на платформе установлена ​​правильная версия.NET Core.

Фон

Я пытаюсь получить удобный пользовательский опыт для запуска некоторых утилит, которые иногда полезны, но редко когда-либо необходимы. Поскольку представляется невозможным использовать тот же .DLL на который ссылается клиентское приложение как на консольное приложение, лучше всего было бы иметь один файл, который можно было бы загрузить и запустить без каких-либо зависимостей.

Например, в Java вы можете просто скачать .jar файл на любой поддерживаемой платформе и запустите:

java <package>.jar <namespace>.SomeClass [args]

и он будет "просто работать" без каких-либо дополнительных файлов. Как я могу получить аналогичный пользовательский опыт при использовании.NET Core?

Короче говоря, я хочу попытаться избежать дополнительного шага "сначала распаковать в каталог"...

1 ответ

Решение

Обновление 2018:.NET Core 3.0 призван обеспечить новый сценарий: упаковка среды выполнения.NET Core и всех зависимостей приложений в один исполняемый файл.

На данный момент не существует отказоустойчивых методов для создания одного исполняемого файла. Поскольку задействовано много dll-файлов для переадресации типов, даже ILMerge и аналогичные инструменты могут не давать правильных результатов (хотя это может улучшиться, проблема в том, что эти сценарии не прошли обширное тестирование, особенно в производственных приложениях)

В настоящее время существует два способа развертывания приложения.NET Core:

  • Как "переносимое приложение" / "зависящее от фреймворка приложение", требующее dotnet исполняемый и установленный фреймворк на целевой машине. Здесь XYZ.runtimeconfig.json используется для определения используемой версии платформы, а также для определения параметров времени выполнения. Эта модель развертывания позволяет запускать один и тот же код на разных платформах (windows, linux, mac)
  • Как "автономное приложение": здесь вся среда выполнения включена в опубликованный вывод и генерируется исполняемый файл (например, yourapp.exe). Эти выходные данные относятся к платформе (задается с помощью идентификатора среды выполнения) и могут выполняться только в целевой операционной системе. Тем не менее, производимый исполняемый файл является лишь небольшой оболочкой, которая загружает среду выполнения и загружает основной файл DLL приложения. Это также позволяет XYZ.runtimeconfig.json установить дополнительные свойства времени выполнения, такие как настройки сборки мусора. (Думайте об этом как о "новом" app.config файл)

В будущем среда выполнения CoreRT, которая еще находилась в стадии разработки, нацелена на то, чтобы позволить создать один предварительно скомпилированный собственный исполняемый файл, специфичный для среды выполнения и не требующий никаких других файлов.

Протестировано с.NET Core 2.2 в консольном приложении:

  1. Ссылка на пакет Microsoft.DotNet.ILCompiler в вашем выходном проекте. Вам нужно будет добавить репозиторий пакетов MyGet в настройках Visual Studio. *
  2. Опубликуйте проект через командную строку, dotnet опубликуйте C: \ src \ App \ App.csproj -c release -r win-x64 -o output-win-x64. Если не установлен компонент "Разработка рабочего стола для C++", выполните это в установщике Visual Studio, иначе команда не будет выполнена.
  3. Перейдите в папку вывода (например, "C:\src\App\output-win-x64") и возьмите собственное изображение (файл.exe).

В Windows он создал полнофункциональный файл размером 5 МБ.exe (по сравнению с оригинальной автономной публикацией с размером папки ~60 МБ). В macOS ILComplier, хотя и выводил данные без каких-либо ошибок, приложение зависало с необработанным ожиданием (на строке с выражением LINQ).

* Перейдите в "Инструменты -> Параметры -> Диспетчер пакетов -> Источники пакетов" и добавьте новый источник по адресу https://dotnet.myget.org/F/dotnet-core/api/v3/index.json

Это возможно в.NET Core 3.0

Эта функция активируется при использовании следующего свойства в файле проекта (.csproj):

<PropertyGroup>
    <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

Есть и другие варианты, например, упаковка pdb в пакет или исключение определенных файлов.

Документацию найти нелегко (так как это все еще предварительная версия), но есть обширный документ со стадии предложения, в котором указывается его использование: https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md

Правда просто работает:

Комбинируя этот метод с рабочим процессом автономного развертывания, вы можете получить для своего пользователя истинный опыт "это просто работает", им даже не нужно устанавливать среду выполнения.NET Core для запуска вашего приложения.

В настоящее время я развертываю приложения для своих клиентов в виде отдельных файлов .exe.

Подробнее об этом читайте здесь: https://docs.microsoft.com/en-us/dotnet/core/deploying/

Другие вопросы по тегам