Freigeben über


NuGet plattformübergreifende Plug-Ins

In NuGet 4.8+ wurde Unterstützung für plattformübergreifende Plug-Ins hinzugefügt. Dies wurde durch die Erstellung eines neuen Plug-In-Erweiterbarkeitsmodells erreicht, das einer strengen Reihe von Betriebsregeln entsprechen muss. Die Plug-Ins sind eigenständige ausführbare Dateien (Runnables in der .NET Core-Welt), die die NuGet-Clients in einem separaten Prozess starten. Dies ist ein echtes "Write Once, Run Everywhere"-Plugin. Es funktioniert mit allen NuGet-Clienttools. Die Plug-Ins können in jeder Programmiersprache geschrieben werden, aber die einfachste Plug-In-Entwicklung und Installationserfahrung ist mit .NET. Ein versionsiertes Kommunikationsprotokoll zwischen dem NuGet-Client und dem Plug-In wird definiert. Während des Start-Handshakes verhandeln die zwei Prozesse die Protokollversion.

Wie funktioniert das?

Der allgemeine Workflow kann wie folgt beschrieben werden:

  1. NuGet ermittelt verfügbare Plug-Ins.
  2. Wenn zutreffend, iteriert NuGet die Plug-Ins in der Prioritätsreihenfolge und startet sie nacheinander.
  3. NuGet verwendet das erste Plug-In, das die Anforderung bedienen kann.
  4. Die Plug-Ins werden heruntergefahren, wenn sie nicht mehr benötigt werden.

Allgemeine Plug-In-Anforderungen

Die aktuelle Protokollversion ist 2.0.0. Unter dieser Version sind die Anforderungen wie folgt:

  • Unterstützen Sie das zustandslose Starten unter dem aktuellen Sicherheitskontext der NuGet-Client-Tools. NuGet-Clienttools führen z. B. keine Erhöhung oder zusätzliche Initialisierung außerhalb des später beschriebenen Plug-In-Protokolls durch.
  • Nicht interaktiv sein, außer bei ausdrücklicher Angabe.
  • Halten Sie sich an die ausgehandelte Plug-In-Protokollversion.
  • Antworten Sie innerhalb eines angemessenen Zeitraums auf alle Anfragen.
  • Berücksichtigen Sie Stornierungsanfragen für alle aktuell laufenden Vorgänge.

Plug-Ins, die von der PATH-Umgebungsvariable (z. B. installiert über dotnet tool) ermittelt werden, müssen zusätzlich mit dem Dateinamenmuster nuget-plugin-*übereinstimmen. Der nuget-plugin- Teil muss vollständig in Kleinbuchstaben geschrieben werden.

NuGet 6.12 (MSBuild 17.12 und .NET SDK 9.0.100) und frühere Versionen erforderten auch, dass Plug-ins unter Windows mit Authenticode signiert sind.

Die technische Spezifikation wird in den folgenden Spezifikationen ausführlicher beschrieben:

Client – Plug-In-Interaktion

NuGet-Clienttools und die Plug-Ins kommunizieren mit JSON über Standardstreams (stdin, stdout, stderr). Alle Daten müssen UTF-8-codiert sein. Die Plugins werden mit dem Argument "-Plugin" gestartet. Falls ein Benutzer ein Plug-In ohne dieses Argument direkt startet, kann das Plug-In eine informative Nachricht geben, anstatt auf einen Protokoll-Handshake zu warten. Das Protokoll-Handshake-Timeout beträgt 5 Sekunden. Das Plug-In sollte das Setup in möglichst kurzer Zeit abschließen. NuGet-Clienttools fragen die unterstützten Vorgänge eines Plug-Ins ab, indem der Dienstindex für eine NuGet-Quelle übergeben wird. Ein Plug-In kann den Dienstindex verwenden, um nach dem Vorhandensein unterstützter Diensttypen zu suchen.

Die Kommunikation zwischen den NuGet-Clienttools und dem Plug-In ist bidirektional. Jede Anforderung hat ein Timeout von 5 Sekunden. Wenn Vorgänge länger dauern sollen, sollte der jeweilige Prozess eine Statusmeldung senden, um zu verhindern, dass die Anforderung eine Zeitüberschreitung vornimmt. Nach 1 Minute Inaktivität gilt ein Plug-In als im Leerlauf und wird heruntergefahren.

Plug-In-Installation und Ermittlung

NuGet sucht nach Plug-Ins aus einer konventionsbasierten Verzeichnisstruktur und scannt die PATH-Umgebungsvariable.

Konventionsbasierte Entdeckung

CI/CD-Szenarien und Power Users können Umgebungsvariablen verwenden, um das Verhalten außer Kraft zu setzen. Bei Verwendung von Umgebungsvariablen sind nur absolute Pfade zulässig. Beachten Sie, dass NUGET_NETFX_PLUGIN_PATHS und NUGET_NETCORE_PLUGIN_PATHS nur mit 5.3+ Version des NuGet-Tools und höher verfügbar sind.

  • NUGET_NETFX_PLUGIN_PATHS - definiert die Plugins, die von den .NET Framework-basierten Entwicklungswerkzeugen verwendet werden (NuGet.exe/MSBuild.exe/Visual Studio). Hat Vorrang vor NUGET_PLUGIN_PATHS. (Nur NuGet-Version 5.3+)
  • NUGET_NETCORE_PLUGIN_PATHS - definiert die Plug-Ins, die von dem auf .NET Core basierenden Tooling (dotnet.exe) verwendet werden. Hat Vorrang vor NUGET_PLUGIN_PATHS. (Nur NuGet-Version 5.3+)
  • NUGET_PLUGIN_PATHS – definiert die Plug-Ins, die für diesen NuGet-Prozess verwendet werden, wobei die Priorität beibehalten wird. Wenn diese Umgebungsvariable festgelegt ist, überschreibt sie die konventionsbasierte Ermittlung. Wird ignoriert, wenn eine der frameworkspezifischen Variablen angegeben ist.
  • Speicherort des Benutzers, der Speicherort von NuGet Home in %UserProfile%/.nuget/plugins. Dieser Speicherort kann nicht außer Kraft gesetzt werden. Ein anderes Stammverzeichnis wird für .NET Core- und .NET Framework-Plug-Ins verwendet.
Rahmenwerk Ort der Root-Erkennung Verwendet von
.NET Kern %UserProfile%/.nuget/plugins/netcore dotnet-CLI
.NET Framework %UserProfile%/.nuget/plugins/netfx MSBuild, NuGet.exe, Visual Studio

Jedes Plug-In sollte in einem eigenen Ordner installiert werden. Der Plug-In-Einstiegspunkt ist der Name des installierten Ordners mit den .dll Erweiterungen für .NET Core und .exe Erweiterung für .NET Framework.

.nuget
    plugins
        netfx
            myPlugin
                myPlugin.exe
                nuget.protocol.dll
                ...
        netcore
            myPlugin
                myPlugin.dll
                nuget.protocol.dll
                ...

PATH-Ermittlung

Ab NuGet 6.13 durchsucht NuGet jedes Verzeichnis in der PATH-Umgebungsvariable nach Dateien, die dem Muster nuget-plugin-*entsprechen. Bei dem Musterabgleich wird die Groß-/Kleinschreibung beachtet und nuget-plugin- muss vollständig in Kleinbuchstaben geschrieben werden. Unter Windows muss die Datei über eine .exe Oder .bat Erweiterung verfügen. Unter Linux und Mac muss die Datei über den ausführbaren Bitsatz verfügen.

Auf diese Weise können NuGet-Plug-Ins über dotnet tool Befehle, WinGet, den Paket-Manager einer Linux-Verteilung oder eine andere Methode installiert werden, die ausführbare Dateien auf dem PATH des Benutzers platzieren kann. Dadurch können NuGet-Plug-Ins auch in jeder Programmiersprache geschrieben werden (zuvor müssen Plug-Ins für Linux und Mac in .NET geschrieben werden).

Es wird empfohlen, Plug-Ins in .NET zu entwickeln, damit Sie das NuGet.Protocol-Paket verwenden können, um zu vermeiden, dass der JSON-RPC-Code geschrieben werden muss, und damit Kunden Ihr Plug-In über dotnet package search nuget-pluginentdecken können.

Unterstützte Vorgänge

Zwei Vorgänge werden unter dem neuen Plug-In-Protokoll unterstützt.

Vorgangsname Mindestprotokollversion Minimale NuGet-Clientversion
Paket herunterladen 1.0.0 4.3.0
Authentifizierung 2.0.0 4.8.0

Ausführen von Plug-Ins unter der richtigen Laufzeit

Für nuGet in dotnet.exe Szenarien müssen Plug-Ins unter dieser spezifischen Laufzeit des dotnet.exeausgeführt werden können. Es liegt in der Verantwortung des Plug-In-Anbieters und des Verbrauchers, sicherzustellen, dass eine kompatible dotnet.exe-/Plugin-Kombination genutzt wird. Ein potenzielles Problem könnte bei den Benutzerstandort-Plug-Ins auftreten, wenn beispielsweise eine dotnet.exe unter der 2.0-Runtime versucht, ein Plug-In zu verwenden, das für die 2.1-Runtime geschrieben wurde.

Zwischenspeichern von Funktionen

Die Sicherheitsüberprüfung und Instanziierung der Plug-Ins ist kostspielig. Der Downloadvorgang erfolgt häufiger als der Authentifizierungsvorgang. Der durchschnittliche NuGet-Benutzer verfügt jedoch nur über ein Authentifizierungs-Plug-In. Um die Benutzererfahrung zu verbessern, speichert NuGet die Vorgangsansprüche für die angegebene Anforderung zwischen. Dieser Cache ist pro Plug-In, wobei der Plug-In-Schlüssel der Plug-In-Pfad ist, und der Ablauf für diesen Funktionscache beträgt 30 Tage.

Der Cache befindet sich in %LocalAppData%/NuGet/plugins-cache und wird mit der Umgebungsvariable NUGET_PLUGINS_CACHE_PATHüberschrieben. Um diesen Cache zu löschen, kann der Befehl "Locals" mit der plugins-cache Option ausgeführt werden. Die all Option "Locals" löscht nun auch den Plug-In-Cache.

Protokollnachrichtenindex

Nachrichten zur Protokollversion 1.0.0:

  1. Schließen

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält keine Nutzlast.
    • Es wird keine Antwort erwartet. Die richtige Antwort ist, dass der Plug-In-Prozess umgehend beendet wird.
  2. Kopieren von Dateien im Paket

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • die Paket-ID und -Version
      • Standort des Paketquellen-Repositorys
      • Pfad des Zielverzeichnisses
      • eine Aufzählung von Dateien im Paket, die in den Zielverzeichnispfad kopiert werden sollen
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • eine Aufzählung der vollständigen Pfade für kopierte Dateien im Zielverzeichnis, wenn der Vorgang erfolgreich war
  3. Kopieren der Paketdatei (.nupkg)

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • die Paket-ID und -Version
      • Speicherort des Quell-Repositorys des Pakets
      • Der Zieldateipfad
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
  4. Abrufen von Anmeldeinformationen

    • Anforderungsrichtung: Plugin -> NuGet
    • Die Anforderung enthält Folgendes:
      • Speicherort des Paketquellen-Repositorys
      • der HTTP-Statuscode, der mit den aktuellen Zugangsdaten aus dem Paketquellen-Repository abgerufen wurde
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • ein Benutzername, falls verfügbar
      • ein Kennwort, falls verfügbar
  5. Abrufen von Dateien im Paket

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • die Paket-ID und -Version
      • Standort des Paketquellen-Repositorys
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • eine Aufzählung von Dateipfaden im Paket, wenn der Vorgang erfolgreich war
  6. Abrufen von Betriebsansprüchen

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • der Dienst index.json für eine Paketquelle
      • Speicherort des Paketquell-Repositorys
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • eine Aufzählung der unterstützten Vorgänge (z. B. Paketdownload), wenn der Vorgang erfolgreich war. Wenn ein Plug-In die Paketquelle nicht unterstützt, muss das Plug-In einen leeren Satz unterstützter Vorgänge zurückgeben.

Hinweis

Diese Nachricht wurde in Version 2.0.0 aktualisiert. Es liegt beim Client, die Abwärtskompatibilität zu bewahren.

  1. Pakethash abrufen

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • die Paket-ID und -Version
      • Speicherort des Paketquell-Repositorys
      • Der Hashalgorithmus
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • ein Paketdateihash mit dem angeforderten Hashalgorithmus, wenn der Vorgang erfolgreich war
  2. Paketversionen abrufen

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • die Paket-ID
      • Speicherort des Repositorys der Paketquelle
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • eine Aufzählung der Paketversionen, wenn der Vorgang erfolgreich war
  3. Dienstindex abrufen

    • Anfragerichtung: Plugin -> NuGet
    • Die Anforderung enthält Folgendes:
      • Speicherort des Paketquellen-Repositorys
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • der Dienstindex, wenn der Vorgang erfolgreich war
  4. Händedruck

    • Anforderungsrichtung: NuGet <-> Plugin
    • Die Anforderung enthält Folgendes:
      • aktuelle Plug-In-Protokollversion
      • mindestens unterstützte Plug-In-Protokollversion
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • die ausgehandelte Protokollversion, wenn der Vorgang erfolgreich war. Ein Fehler führt zum Beenden des Plug-Ins.
  5. Initialisieren

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • Die NuGet-Clienttoolversion
      • Die effektive Programmiersprache des NuGet-Clients. Dies berücksichtigt die Einstellung ForceEnglishOutput, sofern sie verwendet wird.
      • das Standardanforderungs-Timeout, das den Protokollstandard überschreibt.
    • Eine Antwort enthält Folgendes:
      • ein Antwortcode, der das Ergebnis des Vorgangs angibt. Ein Fehler führt zum Beenden des Plug-Ins.
  6. Protokoll

    • Anforderungsrichtung: Plugin -> NuGet
    • Die Anforderung enthält Folgendes:
      • die Protokollebene für die Anforderung
      • eine zu protokollierende Nachricht
    • Eine Antwort enthält Folgendes:
      • ein Antwortcode, der das Ergebnis des Vorgangs angibt.
  7. Überwachung des Abschlusses des NuGet-Prozesses

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • Die NuGet-Prozess-ID
    • Eine Antwort enthält Folgendes:
      • ein Antwortcode, der das Ergebnis des Vorgangs angibt.
  8. Prefetch-Paket

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • die Paket-ID und -Version
      • Speicherort des Paketquellen-Repositorys
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
  9. Festlegen von Anmeldeinformationen

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • Speicherort des Paketquellen-Repositorys
      • der letzte bekannte Benutzername der Paketquelle, falls verfügbar
      • das letzte bekannte Paketquellkennwort, falls verfügbar
      • der letzte bekannte Proxybenutzername, falls verfügbar
      • das letzte bekannte Proxykennwort, falls verfügbar
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
  10. Protokollebene festlegen

    • Anforderungsrichtung: NuGet -> Plugin
    • Die Anforderung enthält Folgendes:
      • Standardprotokollstufe
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt

Protokollversion 2.0.0-Nachrichten

  1. Abrufen von Vorgangsansprüchen
  • Anforderungsrichtung: NuGet -> Plugin

    • Die Anforderung enthält Folgendes:
      • der Dienst index.json für eine Paketquelle
      • Speicherort des Paketquellen-Repositorys
    • Eine Antwort enthält Folgendes:
      • Antwortcode, der das Ergebnis des Vorgangs angibt
      • eine Aufzählung der unterstützten Vorgänge, wenn der Vorgang erfolgreich war. Wenn ein Plug-In die Paketquelle nicht unterstützt, muss das Plug-In einen leeren Satz unterstützter Vorgänge zurückgeben.

    Wenn der Dienstindex und die Paketquelle NULL sind, kann das Plug-In mit Authentifizierung antworten.

  1. Authentifizierungsdaten abrufen
  • Anforderungsrichtung: NuGet -> Plugin
  • Die Anforderung enthält Folgendes:
    • Uri
    • isRetry
    • Nicht interaktiv
    • CanShowDialog
  • Eine Antwort wird enthalten
    • Nutzername
    • Passwort
    • Nachricht
    • Liste der Authentifizierungstypen
    • Nachrichtenantwortcode