Plattformübergreifende NuGet-Plug-Ins
In NuGet 4.8 und höher wurde Unterstützung für plattformübergreifende Plug-Ins hinzugefügt. Dies wurde durch das Entwickeln eines neuen Plug-in-Erweiterbarkeitsmodells erreicht, das einem strengen Satz von Vorgangsregeln genügen muss. Die Plug-Ins sind eigenständige ausführbare Dateien („Runnables“ im .NET Core-Sprachgebrauch), die von den NuGet-Clients in einem separaten Prozess gestartet werden. Es handelt sich um echte Plug-Ins vom Typ „write once, run everywhere“. Sie funktionieren mit allen NuGet-Clienttools. Die Plug-Ins können vom Typ .NET Framework („NuGet.exe“, „msbuild.exe“ und Visual Studio) oder .NET Core („dotnet.exe“) sein. Ein Kommunikationsprotokoll mit Versionsangabe ist zwischen dem NuGet-Client und dem Plug-In definiert. Während des Starthandshakes handeln die beiden Prozesse die Protokollversion aus.
Um alle Szenarien für NuGet-Clienttools abzudecken, benötigen Sie ein .NET Framework- und ein .NET Core-Plug-In. Im Folgenden werden die Client-/Frameworkkombinationen der Plug-Ins beschrieben.
Clienttool | Framework |
---|---|
Visual Studio | .NET Framework |
dotnet.exe | .NET Core |
NuGet.exe | .NET Framework |
MSBuild.exe | .NET Framework |
NuGet.exe unter Mono | .NET Framework |
Wie funktioniert das?
Der allgemeine Workflow kann wie folgt beschrieben werden:
- NuGet erkennt verfügbare Plug-Ins.
- Wenn zutreffend, durchläuft NuGet die Plug-Ins in der Reihenfolge der Priorität und startet sie nacheinander.
- NuGet verwendet das erste Plug-In, das die Anforderung bedienen kann.
- 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 gelten die folgenden Anforderungen:
- Es sind gültige, vertrauenswürdige Authenticode-Signaturassemblys vorhanden, die unter Windows und Mono ausgeführt werden. Für Assemblys, die unter Linux und Mac ausgeführt werden, ist keine besondere Vertrauensstellung erforderlich. Relevantes Problem
- Unterstützung des zustandslosen Starts im aktuellen Sicherheitskontext der NuGet-Clienttools. Beispielsweise führen die NuGet-Clienttools keine Erhöhung von Rechten oder zusätzliche Initialisierung außerhalb des später beschriebenen Plug-In-Protokolls aus.
- Nicht interaktives Verhalten, wenn nicht explizit angegeben.
- Verwenden der ausgehandelten Plug-In-Protokollversion.
- Reagieren auf alle Anforderungen innerhalb eines angemessenen Zeitraums.
- Beachten von Abbruchanforderungen für alle aktuell ausgeführten Vorgänge.
Die technische Spezifikation wird in den folgenden Spezifikationen ausführlicher beschrieben:
Interaktion zwischen Client und Plug-In
Die NuGet-Clienttools und die Plug-Ins kommunizieren mit JSON über Standardstreams (stdin, stdout, stderr). Alle Daten müssen UTF-8-codiert sein. Die Plug-Ins werden mit dem Argument „-Plugin“ gestartet. Wenn ein Benutzer eine ausführbare Plug-In-Datei ohne dieses Argument direkt startet, kann das Plug-In eine informative Nachricht ausgeben, anstatt auf einen Protokollhandshake zu warten. Das Timeout für den Protokollhandshake beträgt 5 Sekunden. Das Plug-In sollte das Setup in möglichst kurzer Zeit abschließen. NuGet-Clienttools fragen die von einem Plug-In unterstützten Vorgänge ab, indem sie den Dienstindex für eine NuGet-Quelle übergeben. Ein Plug-In kann den Dienstindex verwenden, um das Vorhandensein von unterstützten Diensttypen zu überprüfen.
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 auslöst. Nach 1 Minute Inaktivität gilt ein Plug-in als im Leerlauf und wird heruntergefahren.
Installation und Ermittlung von Plug-Ins
Die Plug-Ins werden über eine auf Konventionen basierende Verzeichnisstruktur ermittelt.
CI/CD-Szenarien und Poweruser können Umgebungsvariablen verwenden, um das Verhalten zu überschreiben. Wenn Umgebungsvariablen verwendet werden, sind nur absolute Pfade zulässig. Beachten Sie, dass NUGET_NETFX_PLUGIN_PATHS
und NUGET_NETCORE_PLUGIN_PATHS
nur mit Version 5.3 oder höher der NuGet-Tools verfügbar sind.
NUGET_NETFX_PLUGIN_PATHS
: Definiert die Plug-Ins, die von den auf .NET Framework basierenden Tools (nuget.exe/msbuild.exe/Visual Studio) verwendet werden. Besitzt Vorrang vorNUGET_PLUGIN_PATHS
. (Nur NuGet-Version 5.3 oder höher)NUGET_NETCORE_PLUGIN_PATHS
: Definiert die Plug-Ins, die von den auf .NET Core basierenden Tools (dotnet.exe) verwendet werden. Besitzt Vorrang vorNUGET_PLUGIN_PATHS
. (Nur NuGet-Version 5.3 oder höher)NUGET_PLUGIN_PATHS
: Definiert die Plug-Ins, die für den NuGet-Prozess verwendet werden. Die Priorität wird beibehalten. Wenn diese Umgebungsvariable festgelegt ist, wird die auf der Konvention basierende Ermittlung überschrieben. Wird ignoriert, wenn eine der frameworkspezifischen Variablen angegeben wird.- User-location, der NuGet-Startspeicherort in
%UserProfile%/.nuget/plugins
. Dieser Speicherort kann nicht überschrieben werden. Für .NET Core- und .NET Framework-Plug-Ins wird ein anderes Stammverzeichnis verwendet.
Framework | Ermittlung des Stammverzeichnisses |
---|---|
.NET Core | %UserProfile%/.nuget/plugins/netcore |
.NET Framework | %UserProfile%/.nuget/plugins/netfx |
Jedes Plug-In sollte in einem eigenen Ordner installiert werden. Der Plug-In-Einstiegspunkt ist der Name des installierten Ordners mit der DLL-Erweiterung für .NET Core und der EXE-Erweiterung für .NET Framework.
.nuget
plugins
netfx
myPlugin
myPlugin.exe
nuget.protocol.dll
...
netcore
myPlugin
myPlugin.dll
nuget.protocol.dll
...
Hinweis
Zurzeit gibt es keine User Story für die Installation der Plug-Ins. Die Installation ist ganz einfach: Sie verschieben die erforderlichen Dateien an den vordefinierten Speicherort.
Unterstützte Vorgänge
Unter dem neuen Plug-In-Protokoll werden zwei Vorgänge unterstützt.
Vorgangsname | Mindestprotokollversion | Mindestversion des NuGet-Clients |
---|---|---|
Downloadpaket | 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 bestimmten Laufzeit von „dotnet.exe“ ausgeführt werden können. Der Plug-In-Anbieter und der Consumer sind für die Sicherstellung verantwortlich, dass eine kompatible Kombination aus „dotnet.exe“ und Plug-In verwendet wird. Ein potenzielles Problem könnte bei den user-location-Plug-Ins auftreten, wenn beispielsweise eine Datei „dotnet.exe“ unter der 2.0-Laufzeit versucht, ein für die 2.1-Laufzeit geschriebenes Plug-In zu verwenden.
Zwischenspeichern von Funktionen
Die Sicherheitsüberprüfung und die Instanziierung der Plug-Ins ist speicherintensiv. Der Downloadvorgang erfolgt viel häufiger als der Authentifizierungsvorgang, aber der durchschnittliche NuGet-Benutzer verfügt wahrscheinlich nur über ein Authentifizierungs-Plug-In. Um die Benutzererfahrung zu optimieren, speichert NuGet die Ansprüche der Vorgänge für die jeweilige Anforderung zwischen. Dieser Cache gilt pro Plug-In. Dabei ist der Plug-In-Schlüssel der Plug-In-Pfad, und der Ablaufzeitraum für diesen Funktionscache beträgt 30 Tage.
Der Cache befindet sich in %LocalAppData%/NuGet/plugins-cache
und wird durch die Umgebungsvariable NUGET_PLUGINS_CACHE_PATH
überschrieben.
Zum Löschen dieses Caches können Sie den locals-Befehl mit der Option plugins-cache
ausführen.
Mit der locals-Option all
wird nun auch der Plug-In-Cache gelöscht.
Protokollnachrichtenindex
Nachrichten der Protokollversion 1.0.0:
Schließen
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält keine Nutzlast
- Es wird keine Antwort erwartet. Die richtige Antwort besteht darin, dass der Plug-In-Prozess umgehend beendet wird.
Kopieren der Dateien im Paket
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- ID und Version des Pakets
- Speicherort des Quellrepositorys des Pakets
- Pfad des Zielverzeichnisses
- Aufzählbares Element von Dateien im Paket, die in den Zielverzeichnispfad kopiert werden sollen
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Aufzählbares Element der vollständigen Pfade für kopierte Dateien im Zielverzeichnis, wenn der Vorgang erfolgreich war
Kopieren der Paketdatei (NUPKG-Datei)
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- ID und Version des Pakets
- Speicherort des Quellrepositorys des Pakets
- Zieldateipfad
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
Abrufen von Anmeldeinformationen
- Anfordern der Richtung: Plugin -> NuGet
- Die Anforderung enthält Folgendes:
- Speicherort des Quellrepositorys des Pakets
- HTTP-Statuscode, der mit den aktuellen AnmeldeiInformationen aus dem Quellrepository des Pakets abgerufen wurde
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Benutzername, falls verfügbar
- Kennwort, falls verfügbar
Abrufen von Dateien im Paket
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- ID und Version des Pakets
- Speicherort des Quellrepositorys des Pakets
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Aufzählbares Element der Dateipfade im Paket, wenn der Vorgang erfolgreich war
Abrufen von Ansprüchen des Vorgangs
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- „index.json“ des Diensts für eine Paketquelle
- Speicherort des Quellrepositorys des Pakets
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Aufzählbares Element unterstützter 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 Meldung wurde in Version 2.0.0 aktualisiert. Sie ist auf dem Client vorhanden, um die Abwärtskompatibilität aufrechtzuerhalten.
Abrufen des Pakethash
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- ID und Version des Pakets
- Speicherort des Quellrepositorys des Pakets
- Hashalgorithmus
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Paketdateihash, der den angeforderten Hashalgorithmus verwendet, wenn der Vorgang erfolgreich war
Abrufen von Paketversionen
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- Paket-ID
- Speicherort des Quellrepositorys des Pakets
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Aufzählbares Element der Paketversionen, wenn der Vorgang erfolgreich war
Abrufen des Dienstindex
- Anfordern der Richtung: Plugin -> NuGet
- Die Anforderung enthält Folgendes:
- Speicherort des Quellrepositorys des Pakets
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Dienstindex, wenn der Vorgang erfolgreich war
Handschlag
- Anfordern der Richtung: NuGet <-> Plugin
- Die Anforderung enthält Folgendes:
- Aktuelle Protokollversion des Protokoll-Ins
- Mindestens unterstützte Plug-In-Protokollversion
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Ausgehandelte Protokollversion, wenn der Vorgang erfolgreich war. Ein Fehler führt zu einer Beendigung des Plug-ins.
Initialize
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- Version des NuGet-Clienttools
- Effektive Sprache des NuGet-Clienttools. Dabei wird die Einstellung ForceEnglishOutput berücksichtigt, wenn vorhanden.
- Standardtimeout der Anforderung, das Vorrang vor dem Standardwert des Protokolls besitzt.
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt. Ein Fehler führt zu einer Beendigung des Plug-ins.
Log
- Anfordern der Richtung: Plugin -> NuGet
- Die Anforderung enthält Folgendes:
- Protokollebene für die Anforderung
- Zu protokollierende Nachricht
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt.
Überwachen der Beendigung eines NuGet-Prozesses
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- NuGet-Prozess-ID
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt.
Vorababruf eines Pakets
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- ID und Version des Pakets
- Speicherort des Quellrepositorys des Pakets
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
Anmeldeinformationen festlegen
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- Speicherort des Quellrepositorys des Pakets
- Benutzername der letzten bekannten Paketquelle, falls verfügbar
- Kennwort der letzten bekannten Paketquelle, falls verfügbar
- Benutzername des letzten bekannten Proxys, falls verfügbar
- Kennwort des letzten bekannten Proxys, falls verfügbar
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
Festlegen der Protokollierungsebene
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- Standardprotokollebene
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
Nachrichten der Protokollversion 2.0.0
- Abrufen von Ansprüchen des Vorgangs
Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- „index.json“ des Diensts für eine Paketquelle
- Speicherort des Quellrepositorys des Pakets
- Eine Antwort enthält Folgendes:
- Antwortcode, der das Ergebnis des Vorgangs angibt
- Aufzählbares Element unterstützter 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.
- Die Anforderung enthält Folgendes:
- Abrufen der Anmeldeinformationen für die Authentifizierung
- Anfordern der Richtung: NuGet -> Plugin
- Die Anforderung enthält Folgendes:
- Uri
- isRetry
- NonInteractive
- CanShowDialog
- Eine Antwort enthält Folgendes
- Benutzername
- Kennwort
- `Message`
- Liste der Authentifizierungstypen
- MessageResponseCode