Поделиться через


Новые возможности пакета SDK и инструментов для .NET 10

В этой статье описываются новые функции и улучшения пакета SDK для .NET для .NET 10.

Усовершенствования средств .NET

Средства .NET для конкретной платформы

Теперь средства .NET можно публиковать с поддержкой нескольких идентификаторов среды выполнения (RID) в одном пакете. Авторы инструментов могут упаковывать двоичные файлы для всех поддерживаемых платформ, а интерфейс командной строки .NET выберет правильный файл при установке или во время выполнения. Это упрощает разработку и распространение кроссплатформенных инструментов.

Эти расширенные средства поддерживают различные варианты упаковки:

  • Зависимость от фреймворка, независимость от платформы (классический режим, выполняется в любом месте при наличии установленного .NET 10)
  • Зависящие от фреймворка, зависящие от платформы (небольшие, оптимизированные для каждой платформы)
  • Автономный, зависящий от платформы (включает среду выполнения, не требуется установка .NET)
  • Упрощенный, специфичный для платформы (меньше, обрезает неиспользуемый код)
  • AOT-скомпилированный, специфичный для платформы (максимальная производительность и минимальный объем развертывания)

Эти новые средства работают так же, как обычные опубликованные приложения, поэтому любые варианты публикации, которые можно использовать с приложениями (например, автономные, обрезанные или AOT), также могут применяться к средствам.

Однократное выполнение инструмента

Теперь можно использовать dotnet tool exec команду для выполнения средства .NET без его глобальной или локальной установки. Это особенно полезно для CI/CD или временного использования.

dotnet tool exec --source ./artifacts/package/ dotnetsay  "Hello, World!"
Tool package [email protected] will be downloaded from source <source>.
Proceed? [y/n] (y): y
  _   _          _   _                __        __                 _       _   _
 | | | |   ___  | | | |   ___         \ \      / /   ___    _ __  | |   __| | | |
 | |_| |  / _ \ | | | |  / _ \         \ \ /\ / /   / _ \  | '__| | |  / _` | | |
 |  _  | |  __/ | | | | | (_) |  _      \ V  V /   | (_) | | |    | | | (_| | |_|
 |_| |_|  \___| |_| |_|  \___/  ( )      \_/\_/     \___/  |_|    |_|  \__,_| (_)
                                |/

При этом выполняется скачивание и запуск указанного пакета средства в одной команде. По умолчанию пользователям предлагается подтвердить загрузку, если средство еще не существует локально. Последняя версия выбранного пакета инструментов используется, если не указана явная версия (например, [email protected]).

Однократное выполнение инструмента легко интегрируется с манифестами локальных инструментов. Если вы запускаете инструмент из расположения, где рядом находится .config/dotnet-tools.json, версия инструмента в этой конфигурации будет использоваться вместо последней доступной версии.

Новый dnx скрипт выполнения инструмента

Скрипт dnx предоставляет упрощенный способ выполнения инструментов. Он перенаправит все аргументы в интерфейс командной dotnet строки для обработки, что делает использование инструментов максимально простым:

dnx dotnetsay "Hello, World!"

Фактическая реализация команды dnx находится в самом интерфейсе командной строки dotnet, что позволяет поведению команды развиваться со временем.

Дополнительные сведения об управлении инструментами .NET см. в разделе "Управление инструментами .NET".

Используйте any RuntimeIdentifier с .NET инструментами, специфичными для платформы.

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

Чтобы сделать инструмент работать таким образом, добавьте идентификатор среды выполнения в any файл проекта:

<PropertyGroup>
  <RuntimeIdentifiers>
       linux-x64;
       linux-arm64;
       macos-arm64;
       win-x64;
       win-arm64;
       any
  </RuntimeIdentifiers>
</PropertyGroup>

Этот идентификатор среды выполнения находится в «корне» проверки совместимости платформы, и поскольку он объявляет поддержку любой платформы, упакованный инструмент будет наиболее совместимым типом инструмента — зависимой от фреймворка, платформо-агностической .NET DLL, которая требует совместимой среды выполнения .NET для исполнения. При создании dotnet pack средства вы увидите новый пакет для any RuntimeIdentifier наряду с другими пакетами, специфичными для платформы, и пакетом верхнего уровня манифеста.

Инспекция интерфейса командной строки с --cli-schema

Новый --cli-schema параметр доступен во всех командах CLI. При использовании он выводит представление JSON дерева команд CLI для вызываемой команды или подкоманда. Это полезно для авторов инструментов, интеграции оболочки и расширенного скрипта.

dotnet clean --cli-schema

Выходные данные предоставляют структурированное, доступное для чтения машинное описание аргументов, параметров и вложенных команд:

{
  "name": "clean",
  "version": "10.0.100-dev",
  "description": ".NET Clean Command",
  "arguments": {
    "PROJECT | SOLUTION": {
      "description": "The project or solution file to operate on. If a file is not specified, the command will search the current directory for one.",
      "arity": { "minimum": 0, "maximum": null }
    }
  },
  "options": {
    "--artifacts-path": {
      "description": "The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path.",
      "helpName": "ARTIFACTS_DIR"
    }
  },
  "subcommands": {}
}

Использование задач .NET MSBuild с .NET Framework MSBuild

MSBuild — это базовая система сборки для .NET, управляющая как сборкой проектов (как видно в командах, таких как dotnet build и dotnet pack), так и в качестве общего средства получения информации о проектах (как демонстрируется командами, такими как dotnet list package, и неявно используется командами типа dotnet run, чтобы выяснить, как проект должен выполняться).

При выполнении dotnet команд CLI используется версия MSBuild, которая поставляется с пакетом SDK для .NET. Однако при использовании Visual Studio или вызове MSBuild напрямую используется версия MSBuild, которая установлена с Visual Studio. Эта разница в среде имеет несколько важных последствий. Самое важное заключается в том, что MSBuild работает в Visual Studio (или через msbuild.exe) — это приложение .NET Framework, а MSBuild, работающее в dotnet CLI, — это приложение .NET. Это означает, что любые задачи MSBuild, написанные для выполнения в .NET, нельзя использовать при сборке в Visual Studio или при использовании msbuild.exe.

Начиная с .NET 10, msbuild.exe и Visual Studio 2026 могут выполнять задачи MSBuild, созданные для .NET. Это означает, что теперь вы можете использовать те же задачи MSBuild при сборке в Visual Studio или используя msbuild.exe, как и при создании с помощью CLI dotnet. Для большинства пользователей .NET это не изменится. Но для авторов пользовательских задач MSBuild это означает, что теперь вы можете писать задачи, нацеленные на .NET, которые будут работать на всех платформах. Цель этого изменения заключается в том, чтобы упростить запись и совместное использование задач MSBuild, а также разрешить авторам задач воспользоваться новейшими функциями в .NET. Кроме того, это изменение снижает трудности, связанные с многоплатформенными задачами для поддержки как .NET Framework, так и .NET, и упрощает работу с версиями зависимостей .NET Framework, которые неявно доступны в среде выполнения MSBuild для .NET Framework.

Настройка задач .NET

Для авторов задач легко выбрать это новое поведение. Просто измените UsingTask объявление, чтобы сообщить MSBuild о вашей задаче.

<UsingTask TaskName="MyTask"
    AssemblyFile="path\to\MyTask.dll"
    Runtime="NET"
    TaskFactory="TaskHostFactory"
/>

Атрибуты Runtime="NET" и TaskFactory="TaskHostFactory" указывают движку MSBuild, как выполнить задачу:

  • Runtime="NET" сообщает MSBuild, что задача создана для .NET (в отличие от .NET Framework).
  • TaskFactory="TaskHostFactory" инструктирует MSBuild использовать TaskHostFactory для выполнения задачи, что является одной из существующих возможностей MSBuild и позволяет выполнять задачи вне процесса.

Предостережения и настройка производительности

Приведенный выше пример — самый простой способ начать работу с задачами .NET в MSBuild, но имеет некоторые ограничения. Поскольку TaskHostFactory всегда выполняет задачи вне основного процесса, новая задача .NET всегда выполняется в отдельном процессе от MSBuild. Это означает, что для выполнения задачи возникают незначительные издержки, так как подсистема MSBuild и задача взаимодействуют через взаимодействие между процессами (IPC), а не обмен данными в процессе. Для большинства задач эта нагрузка является незначительной, но для задач, которые выполняются много раз в сборке или создают много логов, такая нагрузка может быть более значительной.

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

<UsingTask TaskName="MyTask"
    AssemblyFile="path\to\MyTask.dll"
    Runtime="NET"
    TaskFactory="TaskHostFactory"
    Condition="$(MSBuildRuntimeType) == 'Full'"
/>
<UsingTask TaskName="MyTask"
    AssemblyFile="path\to\MyTask.dll"
    Runtime="NET"
    Condition="$(MSBuildRuntimeType) == 'Core'"
/>

Condition Благодаря функции MSBuild можно загружать задачу по-разному в зависимости от того, работает ли MSBuild в .NET Framework (Visual Studio или ) или msbuild.exe.NET (dotnetCLI). В этом примере задача выполняется в отдельном процессе при запуске в Visual Studio или msbuild.exe, но выполняется в том же процессе при запуске в CLI с использованием dotnet. Это обеспечивает лучшую производительность при запуске в интерфейсе командной dotnet строки и одновременно позволяет использовать Task в Visual Studio и msbuild.exe.

Существуют также небольшие технические ограничения, которые следует учитывать при использовании задач .NET в MSBuild— наиболее заметным из них является то, что Host Object функция задач MSBuild еще не поддерживается для задач .NET, выполняющихся вне процесса. Это означает, что если задача использует объект узла, он не будет работать при выполнении в Visual Studio или msbuild.exe. В будущих выпусках планируется дополнительная поддержка хост-объектов.

Улучшения приложений на основе файлов

.NET 10 предоставляет значительные обновления в интерфейсе приложений на основе файлов, включая поддержку публикации и собственные возможности AOT. Общие сведения о приложениях на основе файлов см. в разделе " Приложения на основе файлов " и "Создание и запуск программ C#".

Улучшенные приложения на основе файлов с поддержкой публикации и нативным AOT

Теперь приложения на основе файлов поддерживают публикацию в собственных исполняемых файлах с помощью dotnet publish app.cs команды, что упрощает создание простых приложений, которые можно распространить как собственные исполняемые файлы. Все приложения на основе файлов теперь по умолчанию нацелены на нативную AOT-компиляцию. Если вам нужно использовать пакеты или компоненты, несовместимые с собственным AOT, это можно отключить с помощью #:property PublishAot=false директивы в файле .cs.

Приложения на основе файлов также включают расширенные функции:

  • Ссылка на проект: поддержка ссылок на проекты с помощью директивы #:project .
  • Доступ к путям во время выполнения: пути к файлам и каталогам приложения доступны во время выполнения System.AppContext.GetData.
  • Улучшенная поддержка хешбанга: прямое выполнение команд оболочки с улучшенной обработкой хешбанга, включая поддержку файлов без расширения.

Пример ссылки на проект

#:project ../ClassLib/ClassLib.csproj

var greeter = new ClassLib.Greeter();
var greeting = greeter.Greet(args.Length > 0 ? args[0] : "World");
Console.WriteLine(greeting);

Расширенная поддержка shebang: пример

Теперь можно создать исполняемые файлы C#, которые выполняются непосредственно из оболочки:

#!/usr/bin/env dotnet

Console.WriteLine("Hello shebang!");

Для файлов без расширения:

# 1. Create a single-file C# app with a shebang
cat << 'EOF' > hello.cs
#!/usr/bin/env dotnet
Console.WriteLine("Hello!");
EOF

# 2. Copy it (extensionless) into ~/utils/hello (~/utils is on my PATH)
mkdir -p ~/utils
cp hello.cs ~/utils/hello

# 3. Mark it executable
chmod +x ~/utils/hello

# 4. Run it directly from anywhere
cd ~
hello

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

Дополнительные сведения о собственном AOT см. в статье .NET native AOT.

Очистка ссылок на пакеты, предоставляемые платформой

Начиная с .NET 10 функция аудита NuGet может обрезать ссылки на пакеты, предоставляемые платформой , которые не используются проектом. Эта функция включена по умолчанию для всех фреймворков проекта, который нацелен на >= .NET 10.0 в последней версии пакета SDK. Это изменение помогает уменьшить количество пакетов, которые восстанавливаются и анализируются во время процесса сборки, что может привести к более быстрому времени сборки и сокращению использования дискового пространства. Это также может привести к уменьшению количества ложных срабатываний при аудите NuGet и использовании других механизмов проверки зависимостей.

Если эта функция включена, может появиться сокращение содержимого созданных .deps.json файлов приложений. Все ссылки на пакеты, предоставленные средой выполнения .NET, автоматически удаляются из созданного файла зависимостей. Если прямая ссылка на пакет находится в диапазоне обрезки, PrivateAssets="all" и IncludeAssets="none" применяются.

Хотя эта функция включена по умолчанию для перечисленных TFM, её можно отключить, установив значение RestoreEnablePackagePruning для свойства false в файле проекта или в файле Directory.Build.props.

Более согласованный порядок команд

Начиная с .NET 10, dotnet средство CLI включает новые псевдонимы для распространенных команд, чтобы упростить их запоминать и вводить. Новые команды показаны в следующей таблице.

Новая форма с приоритетом существительного Псевдоним для
dotnet package add dotnet add package
dotnet package list dotnet list package
dotnet package remove dotnet remove package
dotnet reference add dotnet add reference
dotnet reference list dotnet list reference
dotnet reference remove dotnet remove reference

Новые формы с приоритетом существительного соответствуют общим стандартам CLI, что делает dotnet более согласованным с другими инструментами. Хотя глагольные формы продолжают работать, лучше использовать формы с существительными для улучшения читаемости и согласованности в скриптах и документации.

Команды CLI по умолчанию для интерактивного режима в интерактивных терминалах

Теперь --interactive флаг включен по умолчанию для команд CLI в интерактивных терминалах. Это изменение позволяет командам динамически извлекать учетные данные или выполнять другие интерактивные действия, не требуя явного задания флага. Для неинтерактивных сценариев можно отключить интерактивность, указав --interactive false.

Скрипты встроенного автодополнения оболочки по клавише Tab

Теперь dotnet интерфейс командной строки поддерживает создание собственных скриптов завершения вкладок для популярных оболочк с помощью dotnet completions script [SHELL] команды. Поддерживаемые оболочки включают bash, fish, nushell, powershell и zsh. Эти сценарии повышают удобство использования, предоставляя более быстрые и более интегрированные функции завершения вкладок. Например, в PowerShell можно включить автозаполнение, добавив следующее в $PROFILE:

dotnet completions script pwsh | Out-String | Invoke-Expression

Консольные приложения могут создавать образы контейнеров в собственном коде

Консольные приложения теперь могут создавать образы контейнеров через dotnet publish /t:PublishContainer, без необходимости в свойстве <EnableSdkContainerSupport> в файле проекта. Это обеспечивает соответствие поведения консольных приложений поведениям приложений ASP.NET Core и Worker SDK.

Явное управление форматом изображений контейнеров

Новое <ContainerImageFormat> свойство позволяет явно задать формат образов контейнеров либо Docker, или OCI. Это свойство переопределяет поведение по умолчанию, которое зависит от формата базового образа и того, является ли контейнер многоархитектурным.

Поддержка платформы тестирования Майкрософт в dotnet test

Начиная с .NET 10, dotnet test изначально поддерживает Microsoft.Testing.Platform. Чтобы включить эту функцию, добавьте следующую конфигурацию в файл global.json :

{
    "test": {
        "runner": "Microsoft.Testing.Platform"
    }
}

Дополнительные сведения см. в разделе "Тестирование с помощью dotnet test".