Teilen über


Neuerungen im SDK und tooling für .NET 10

In diesem Artikel werden neue Features und Verbesserungen im .NET SDK für .NET 10 beschrieben.

Verbesserungen von .NET-Tools

Plattformspezifische .NET-Tools

.NET-Tools können jetzt mit Unterstützung für mehrere RuntimeIdentifiers (RIDs) in einem einzigen Paket veröffentlicht werden. Toolautoren können Binärdateien für alle unterstützten Plattformen bündeln, und die .NET CLI wählt bei der Installation oder Laufzeit die richtige aus. Dies erleichtert die plattformübergreifende Erstellung und Verteilung von Tools.

Diese erweiterten Tools unterstützen verschiedene Verpackungsvarianten:

  • Framework-abhängig, plattformunabhängig (klassischer Modus, läuft überall mit installierter .NET 10)
  • Frameworkabhängig, plattformspezifisch (kleiner und für jede Plattform optimiert)
  • Eigenständig, plattformspezifisch (umfasst die Laufzeit, keine .NET-Installation erforderlich)
  • Gekürzt, plattformspezifisch (kleiner, entfernt nicht verwendeten Code)
  • AOT-kompiliert, plattformspezifisch (maximale Leistung und kleinste Bereitstellung)

Diese neuen Tools funktionieren ähnlich wie normale veröffentlichte Anwendungen, sodass alle Veröffentlichungsoptionen, die Sie mit Anwendungen (z. B. eigenständige, gekürzte oder AOT) verwenden können, auch auf Tools angewendet werden können.

Einmalige Ausführung eines Tools

Sie können jetzt den dotnet tool exec Befehl verwenden, um ein .NET-Tool auszuführen, ohne es global oder lokal zu installieren. Dies ist besonders wertvoll für CI/CD oder ephemerale Nutzung.

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

Dadurch wird das angegebene Toolpaket in einem Einzigen Befehl heruntergeladen und ausgeführt. Standardmäßig werden Benutzer aufgefordert, den Download zu bestätigen, wenn das Tool noch nicht lokal vorhanden ist. Die neueste Version des ausgewählten Toolpakets wird verwendet, es sei denn, dass eine explizite Version angegeben ist (z. B. dotnetsay@0.1.0).

Die Ausführung eines One-Shot-Tools funktioniert nahtlos mit lokalen Toolmanifesten. Wenn Sie ein Tool von einem Speicherort ausführen, der ein .config/dotnet-tools.json in der Nähe enthält, wird die Version des Tools in dieser Konfiguration verwendet und nicht die neueste verfügbare Version.

Das neue dnx Tool-Ausführungsskript

Das dnx Skript bietet eine optimierte Möglichkeit zum Ausführen von Tools. Es leitet alle Argumente zur Verarbeitung an die dotnet CLI weiter, wodurch die Verwendung von Tools so einfach wie möglich ist:

dnx dotnetsay "Hello, World!"

Die tatsächliche Implementierung des dnx Befehls befindet sich in der dotnet CLI selbst, sodass sich das Verhalten im Laufe der Zeit weiterentwickeln kann.

Weitere Informationen zum Verwalten von .NET-Tools finden Sie unter Verwalten von .NET-Tools.

Verwenden des any RuntimeIdentifiers mit plattformspezifischen .NET-Tools

Das plattformspezifische .NET-Tools-Feature eignet sich hervorragend, um sicherzustellen, dass Tools für bestimmte Plattformen optimiert sind, auf die Sie vorab abzielen. Es gibt jedoch Situationen, in denen Sie nicht alle Plattformen kennen, auf die Sie abzielen möchten, oder manchmal lernen .NET selbst, wie sie eine neue Plattform unterstützen, und Sie möchten, dass Ihr Tool dort auch ausgeführt werden kann.

Damit Ihr Tool auf diese Weise funktioniert, fügen Sie der Projektdatei den any Laufzeitbezeichner hinzu:

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

Dieser RuntimeIdentifier befindet sich am "Stamm" der Plattformkompatibilitätsprüfung und da es die Unterstützung für jede Plattform deklariert, ist das Tool, das verpackt wird, die kompatibelste Art von Tool - eine frameworkabhängige, plattformunabhängige .NET-DLL, die eine kompatible .NET-Runtime zum Ausführen benötigt. Wenn Sie ein dotnet pack ausführen, um Ihr Tool zu erstellen, werden Sie sehen, dass neben den anderen plattformspezifischen Paketen und dem Manifestpaket der obersten Ebene ein neues Paket für den any RuntimeIdentifier erscheint.

CLI-Introspektion mit --cli-schema

Eine neue --cli-schema Option ist für alle CLI-Befehle verfügbar. Bei Verwendung gibt sie eine JSON-Darstellung der CLI-Befehlsstruktur für den aufgerufenen Befehl oder Unterbefehl aus. Dies ist nützlich für Toolautoren, Shellintegration und erweiterte Skripts.

dotnet clean --cli-schema

Die Ausgabe enthält eine strukturierte, maschinenlesbare Beschreibung der Argumente, Optionen und Unterbefehle des Befehls:

{
  "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": {}
}

Verwenden von .NET MSBuild-Aufgaben mit .NET Framework MSBuild

MSBuild ist das zugrunde liegende Buildsystem für .NET, das den Aufbau von Projekten steuert (wie in Befehlen wie dotnet build und dotnet pack), und agiert als quasi-Anbieter von Informationen zu Projekten (wie in Befehlen wie dotnet list package, und wird implizit von Befehlen wie dotnet run genutzt, um herauszufinden, wie ein Projekt ausgeführt werden möchte).

Beim Ausführen von dotnet CLI-Befehlen ist die MSBuild-Version, die verwendet wird, die Version, die mit dem .NET SDK geliefert wird. Wenn Sie jedoch Visual Studio verwenden oder MSBuild direkt aufrufen, ist die Version von MSBuild, die verwendet wird, die, die mit Visual Studio installiert ist. Dieser Umweltunterschied hat einige wichtige Konsequenzen. Am wichtigsten ist, dass MSBuild, das in Visual Studio (oder über msbuild.exe) ausgeführt wird, eine .NET Framework-Anwendung ist, während MSBuild, das in der dotnet CLI ausgeführt wird, eine .NET-Anwendung ist. Dies bedeutet, dass alle MSBuild-Aufgaben, die für die Ausführung auf .NET geschrieben wurden, beim Erstellen in Visual Studio oder bei Verwendung msbuild.exenicht verwendet werden können.

Ab .NET 10 und Visual Studio 2026 können msbuild.exe MSBuild-Aufgaben ausführen, die für .NET erstellt wurden. Dies bedeutet, dass Sie jetzt dieselben MSBuild-Aufgaben verwenden können, wenn Sie in Visual Studio erstellen oder msbuild.exe wie beim Erstellen mit der dotnet CLI verwenden. Für die meisten .NET-Benutzer ändert sich dies nicht. Aber für Autoren von benutzerdefinierten MSBuild-Aufgaben bedeutet dies, dass Sie ihre Aufgaben jetzt für .NET schreiben und überall arbeiten lassen können. Das Ziel dieser Änderung besteht darin, das Schreiben und Freigeben von MSBuild-Aufgaben zu vereinfachen und Aufgabenautoren zu ermöglichen, die neuesten Features in .NET zu nutzen. Darüber hinaus verringert diese Änderung die Schwierigkeiten bei Aufgaben mit mehrfacher Zielbestimmung, um .NET Framework und .NET zu unterstützen, und den Umgang mit Versionen von .NET Framework-Abhängigkeiten, die implizit im MSBuild .NET Framework-Ausführungsbereich verfügbar sind.

Konfigurieren von .NET-Aufgaben

Für Aufgabenautoren ist es einfach, sich für dieses neue Verhalten zu entscheiden. Ändern Sie einfach Ihre UsingTask Deklaration, um MSBuild über Ihre Aufgabe zu informieren.

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

Die Attribute Runtime="NET" und TaskFactory="TaskHostFactory" geben der MSBuild-Engine an, wie die Aufgabe ausgeführt wird.

  • Runtime="NET" weist MSBuild an, dass die Aufgabe für .NET (im Gegensatz zu .NET Framework) erstellt wird.
  • TaskFactory="TaskHostFactory" weist MSBuild an, die TaskHostFactory zu verwenden, um die Task auszuführen, was eine vorhandene Funktion von MSBuild ist, die es ermöglicht, Tasks außerhalb des Prozesses auszuführen.

Hinweise und Leistungsoptimierung

Das vorangehende Beispiel ist die einfachste Methode, um mit .NET-Aufgaben in MSBuild zu beginnen, hat jedoch einige Einschränkungen. Da die TaskHostFactory Vorgänge immer außerhalb des Prozesses ausgeführt werden, wird die neue .NET-Aufgabe immer in einem separaten Prozess von MSBuild ausgeführt. Dies bedeutet, dass es einen geringfügigen Aufwand für die Ausführung der Aufgabe gibt, da das MSBuild-Modul und die Aufgabe über die Kommunikation zwischen Prozessen (Inter-Process Communication, IPC) statt in der Prozesskommunikation kommunizieren. Bei den meisten Vorgängen ist dieser Aufwand vernachlässigbar, aber bei Vorgängen, die in einem Build oft ausgeführt werden oder die viele Protokollierungen ausführen, kann dieser Aufwand erheblicher sein.

Mit nur wenig zusätzlichem Aufwand können Sie die Aufgabe so konfigurieren, dass sie weiterhin im Prozess ausgeführt wird, wenn sie über 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'"
/>

Dank des Condition Features von MSBuild können Sie eine Aufgabe unterschiedlich laden, je nachdem, ob MSBuild in .NET Framework (Visual Studio oder msbuild.exe) oder .NET (cli dotnet ) ausgeführt wird. In diesem Beispiel wird die Aufgabe beim Ausführen in Visual Studio oder msbuild.exe außerhalb des Prozesses ausgeführt, aber beim Ausführen in der dotnet CLI innerhalb des Prozesses ausgeführt. Dies bietet die bestmögliche Leistung, wenn es in der dotnet CLI ausgeführt wird, während die Nutzung des Tasks in Visual Studio und msbuild.exe weiterhin möglich ist.

Es gibt auch kleine technische Einschränkungen, die beachtet werden müssen, wenn .NET-Aufgaben in MSBuild verwendet werden – am bemerkenswertesten ist, dass das Host Object-Feature von MSBuild-Aufgaben für .NET-Aufgaben, die außerhalb des Prozesses ausgeführt werden, noch nicht unterstützt wird. Dies bedeutet, dass Ihre Aufgabe bei Abhängigkeit von einem Host-Objekt nicht funktioniert, wenn sie in Visual Studio oder msbuild.exe ausgeführt wird. Zusätzliche Unterstützung für Hostobjekte ist in zukünftigen Versionen geplant.

Verbesserungen an dateibasierten Apps

.NET 10 bietet erhebliche Updates für die dateibasierte App-Erfahrung, einschließlich der Veröffentlichungsunterstützung und systemeigenen AOT-Funktionen. Eine Einführung in dateibasierte Apps finden Sie unter "Dateibasierte Apps " und " Erstellen und Ausführen von C#-Programmen".

Erweiterte dateibasierte Apps mit Veröffentlichungsunterstützung und systemeigenem AOT

Dateibasierte Apps unterstützen jetzt die Veröffentlichung in nativen ausführbaren Dateien über den dotnet publish app.cs Befehl, wodurch es einfacher ist, einfache Apps zu erstellen, die Sie als systemeigene ausführbare Dateien weiterverteilen können. Alle dateibasierten Apps zielen standardmäßig auf systemeigene AOT ab. Wenn Sie Pakete oder Features verwenden müssen, die nicht mit systemeigenem AOT kompatibel sind, können Sie dies mithilfe der #:property PublishAot=false Direktive in Ihrer .cs-Datei deaktivieren.

Dateibasierte Apps enthalten auch erweiterte Features:

  • Projektreferenzierung: Unterstützung für das Verweisen auf Projekte über die #:project Direktive.
  • Zugriff auf den Runtime-Pfad: App Datei- und Verzeichnispfade sind zur Laufzeit über System.AppContext.GetData verfügbar.
  • Verbesserte Shebang-Unterstützung: Direkte Shellausführung mit verbesserter Shebang-Behandlung, einschließlich Unterstützung für erweiterungslose Dateien.

Beispiel für Projektreferenzen

#:project ../ClassLib/ClassLib.csproj

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

Beispiel für verbesserte Shebang-Unterstützung

Sie können jetzt ausführbare C#-Dateien erstellen, die direkt aus der Shell ausgeführt werden:

#!/usr/bin/env dotnet

Console.WriteLine("Hello shebang!");

Für erweiterungslose Dateien:

# 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

Diese Verbesserungen machen dateibasierte Apps leistungsstärker und erhalten gleichzeitig ihre Einfachheit für schnelle Skripting- und Prototypszenarien.

Weitere Informationen zu systemeigenem AOT finden Sie unter .NET Native AOT.

Bearbeitung von durch das Framework bereitgestellten Paket-Referenzen

Ab .NET 10 kann das NuGet-Überwachungsfeature Paketverweise, die vom Framework bereitgestellt und nicht vom Projekt verwendet werden, entfernen. Dieses Feature ist standardmäßig für alle Frameworks eines Projekts aktiviert, das auf .NET 10.0 im neuesten SDK abzielt >. Diese Änderung trägt dazu bei, die Anzahl der Pakete zu reduzieren, die während des Buildprozesses wiederhergestellt und analysiert werden, was zu schnelleren Buildzeiten und reduzierter Speicherplatznutzung führen kann. Es kann auch zu einer Verringerung falsch positiver Ergebnisse von NuGet Audit und anderen Abhängigkeitsscanmechanismen führen.

Wenn dieses Feature aktiviert ist, sehen Sie möglicherweise eine Verringerung des Inhalts der generierten .deps.json Dateien Ihrer Anwendungen. Alle von der .NET-Laufzeit bereitgestellten Paketverweise werden automatisch aus der generierten Abhängigkeitsdatei entfernt. Wenn sich ein direkter Paketverweis im Schnittbereich befindet, werden PrivateAssets="all" und IncludeAssets="none" angewendet.

Obwohl dieses Feature für die aufgeführten TFMs standardmäßig aktiviert ist, können Sie es deaktivieren, indem Sie die RestoreEnablePackagePruning-Eigenschaft in der Projektdatei oder in der Datei false auf festlegen.

Konsistentere Befehlsreihenfolge

Ab .NET 10 enthält das dotnet CLI-Tool neue Aliase für allgemeine Befehle, um sie leichter zu merken und einzugeben. Die neuen Befehle werden in der folgenden Tabelle angezeigt.

Neues Nomen-zuerst-Format Alias für .
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

Die neuen Substantivformen entsprechen allgemeinen CLI-Standards, wodurch die dotnet CLI mit anderen Tools konsistenter wird. Während die verb-first-Formulare weiterhin funktionieren, ist es besser, die Substantiv-ersten Formulare für eine verbesserte Lesbarkeit und Konsistenz in Skripts und Dokumentationen zu verwenden.

CLI-Befehle werden standardmäßig im interaktiven Modus in interaktiven Terminals verwendet.

Das --interactive Flag ist jetzt standardmäßig für CLI-Befehle in interaktiven Terminals aktiviert. Diese Änderung ermöglicht es Befehlen, Anmeldeinformationen dynamisch abzurufen oder andere interaktive Verhaltensweisen auszuführen, ohne dass die Kennzeichnung explizit festgelegt werden muss. Bei nichtinteraktiven Szenarien können Sie die Interaktivität deaktivieren, indem Sie angeben --interactive false.

Native Shell-Skripte zur Tab-Vervollständigung

Die dotnet CLI unterstützt jetzt das Generieren nativer Tab-Abschlussskripts für beliebte Shells mit dem dotnet completions script [SHELL] Befehl. Unterstützte Shells umfassen bash, , fish, nushell, powershellund zsh. Diese Skripte verbessern die Benutzerfreundlichkeit, indem sie schnellere und integrierte Funktionen zur Tab-Vervollständigung bereitstellen. In PowerShell können Sie beispielsweise Ergänzungen aktivieren, indem Sie Folgendes zu Ihrem $PROFILE hinzufügen:

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

Konsolen-Apps können containerimages nativ erstellen

Konsolen-Apps können jetzt Container-Images über dotnet publish /t:PublishContainer erstellen, ohne dass die <EnableSdkContainerSupport>-Eigenschaft in der Projektdatei erforderlich ist. Dadurch werden Konsolen-Apps an das Verhalten von ASP.NET Core- und Worker SDK-Apps ausgerichtet.

Explizites Steuern des Bildformats von Containern

Mit einer neuen <ContainerImageFormat>-Eigenschaft können Sie das Format von Container-Images explizit auf entweder Docker oder OCI festlegen. Diese Eigenschaft überschreibt das Standardverhalten, das vom Basisimageformat und davon abhängt, ob es sich bei dem Container um eine Multiarchitektur-Umgebung handelt.

Unterstützung für Microsoft Testing Platform in dotnet test

Ab .NET 10 bietet dotnet test native Unterstützung für Microsoft.Testing.Platform. Um dieses Feature zu aktivieren, fügen Sie ihrer global.json Datei die folgende Konfiguration hinzu:

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

Weitere Details finden Sie unter Testen mit dotnet test.