NuGet 跨平臺外掛程式

已新增跨平臺外掛程式的 NuGet 4.8+ 支援。 這是透過建置新的外掛程式擴充性模型來達成,該模型必須符合一組嚴格的作業規則。 外掛程式是獨立可執行檔(可在 .NET Core 世界中執行),NuGet 用戶端會在個別程序中啟動。 這是真正的寫入一次,請在所有位置執行外掛程式。 它將使用所有 NuGet 用戶端工具。 外掛程式可以是 .NET Framework(NuGet.exe、MSBuild.exe 和 Visual Studio),或 .NET Core (dotnet.exe)。 NuGet 用戶端與外掛程式之間的版本化通訊協定已定義。 在啟動交握期間,2 個進程會交涉通訊協定版本。

為了涵蓋所有 NuGet 用戶端工具案例,一個需要 .NET Framework 和 .NET Core 外掛程式。 以下說明外掛程式的用戶端/架構組合。

用戶端工具 架構
Visual Studio .NET Framework
dotnet.exe .NET Core
NuGet.exe .NET Framework
MSBuild.exe .NET Framework
Mono 上的NuGet.exe .NET Framework

運作方式

高階工作流程可描述如下:

  1. NuGet 會探索可用的外掛程式。
  2. 適用時,NuGet 會依優先順序逐一逐一查看外掛程式,並逐一啟動外掛程式。
  3. NuGet 會使用可服務要求的第一個外掛程式。
  4. 不再需要外掛程式時,這些外掛程式將會關閉。

一般外掛程式需求

目前的通訊協定版本是 2.0.0。 在此版本中,需求如下:

  • 擁有將在 Windows 和 Mono 上執行的有效受信任 Authenticode 簽章元件。 Linux 和 Mac 上執行的元件沒有特殊的信任需求。 相關問題
  • 支援 NuGet 用戶端工具目前安全性內容下的無狀態啟動。 例如,NuGet 用戶端工具不會在稍後所述的外掛程式通訊協定之外執行提高許可權或其他初始化。
  • 除非明確指定,否則為非互動式。
  • 遵守交涉的外掛程式通訊協定版本。
  • 在合理的期間內回應所有要求。
  • 接受任何進行中作業的取消要求。

下列規格會更詳細地說明技術規格:

用戶端 - 外掛程式互動

NuGet 用戶端工具和外掛程式會透過標準數據流與 JSON 通訊(stdin、stdout、stderr)。 所有數據都必須經過UTF-8編碼。 外掛程式會以自變數 「-Plugin」 啟動。 如果使用者直接啟動沒有此自變數的外掛程式可執行檔,外掛程式可以提供資訊訊息,而不是等待通訊協定交握。 通訊協定交握逾時為5秒。 外掛程式應該盡可能短地完成設定。 NuGet 用戶端工具會傳入 NuGet 來源的服務索引,以查詢外掛程式支援的作業。 外掛程式可以使用服務索引來檢查支援的服務類型是否存在。

NuGet 用戶端工具和外掛程式之間的通訊是雙向的。 每個要求都有5秒的逾時。 如果作業應該花費較長的時間,個別進程應該會傳送進度訊息,以防止要求逾時。在閑置 1 分鐘之後,外掛程式就會被視為閑置且已關閉。

外掛程式安裝和探索

外掛程式會透過慣例型目錄結構來探索。 CI/CD 案例和進階使用者可以使用環境變數來覆寫行為。 使用環境變數時,只允許絕對路徑。 請注意, NUGET_NETFX_PLUGIN_PATHSNUGET_NETCORE_PLUGIN_PATHS 僅適用於 5.3+ 版的 NuGet 工具及更新版本。

  • NUGET_NETFX_PLUGIN_PATHS - 定義 .NET Framework 型工具將使用的外掛程式(NuGet.exe/MSBuild.exe/Visual Studio)。 優先權高於 NUGET_PLUGIN_PATHS。 (僅限 NuGet 5.3 版+ )
  • NUGET_NETCORE_PLUGIN_PATHS - 定義 .NET Core 型工具 (dotnet.exe) 將使用的外掛程式。 優先權高於 NUGET_PLUGIN_PATHS。 (僅限 NuGet 5.3 版+ )
  • NUGET_PLUGIN_PATHS - 定義將用於該 NuGet 進程的外掛程式,並保留優先順序。 如果設定此環境變數,則會覆寫慣例型探索。 如果指定其中一個架構特定變數,則會忽略 。
  • 使用者位置,位於中的 %UserProfile%/.nuget/pluginsNuGet 首頁位置。 無法覆寫此位置。 不同的根目錄將用於 .NET Core 和 .NET Framework 外掛程式。
架構 根探索位置
.NET Core %UserProfile%/.nuget/plugins/netcore
.NET Framework %UserProfile%/.nuget/plugins/netfx

每個外掛程式都應該安裝在自己的資料夾中。 外掛程式進入點會是已安裝資料夾的名稱,其中包含 .NET Core 的.dll擴展名,以及 .NET Framework 的.exe擴展名。

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

注意

目前沒有安裝外掛程式的使用者案例。 它就像將必要檔案移至預先決定的位置一樣簡單。

支援的作業

新的外掛程式通訊協定支援兩項作業。

作業名稱 最低通訊協定版本 最低 NuGet 用戶端版本
下載套件 1.0.0 4.3.0
驗證 2.0.0 4.8.0

在正確的運行時間下執行外掛程式

針對dotnet.exe案例中的 NuGet,外掛程式必須能夠在dotnet.exe的特定運行時間下執行。 它位於外掛程式提供者和取用者上,以確保使用相容的dotnet.exe/外掛程式組合。 例如,在 2.0 執行時間下dotnet.exe嘗試使用針對 2.1 運行時間撰寫的外掛程式時,使用者位置外掛程式可能會發生潛在問題。

功能快取

外掛程式的安全性驗證和具現化成本很高。 下載作業會比驗證作業更頻繁,不過平均 NuGet 使用者可能只有驗證外掛程式。 為了改善體驗,NuGet 會快取指定要求的作業宣告。 此快取是每個外掛程式,外掛程式索引鍵為外掛程式路徑,而此功能快取的到期日為30天。

快取位於 中 %LocalAppData%/NuGet/plugins-cache ,並使用環境變數 NUGET_PLUGINS_CACHE_PATH覆寫 。 若要清除此 快取,可以使用 選項執行局部變數命令 plugins-cache 。 局部 all 變數選項現在也會刪除外掛程式快取。

通訊協定訊息索引

通訊協定 1.0.0 版訊息:

  1. 關閉

    • 要求方向:NuGet -> 外掛程式
    • 要求不會包含任何承載
    • 沒有預期的回應。 適當的回應是讓外掛程式程式立即結束。
  2. 複製套件中的檔案

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件識別碼和版本
      • 套件來源存放庫位置
      • 目的地目錄路徑
      • 封裝中要複製到目的地目錄路徑的檔案可列舉
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,則為目的地目錄中複製之檔案的完整路徑可列舉
  3. 複製套件檔案 (.nupkg)

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件識別碼和版本
      • 套件來源存放庫位置
      • 目的地檔案路徑
    • 回應將包含:
      • 指出作業結果的回應碼
  4. 取得認證

    • 要求方向:外掛程式 -> NuGet
    • 要求將包含:
      • 套件來源存放庫位置
      • 使用目前認證從套件來源存放庫取得的 HTTP 狀態代碼
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果有的話,則為用戶名稱
      • 如果可用,則為密碼
  5. 取得套件中的檔案

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件識別碼和版本
      • 套件來源存放庫位置
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,則封裝中的檔案路徑可列舉
  6. 取得作業宣告

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 封裝來源的服務index.json
      • 套件來源存放庫位置
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,可列舉支持的作業(例如:套件下載)。 如果外掛程式不支援套件來源,外掛程式必須傳回空的一組支持作業。

注意

此訊息已在 2.0.0中更新。 它位於用戶端上,以保留回溯相容性。

  1. 取得套件哈希

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件識別碼和版本
      • 套件來源存放庫位置
      • 哈希演算法
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,請使用要求哈希演算法的套件檔案哈希
  2. 取得套件版本

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件識別碼
      • 套件來源存放庫位置
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,可列舉套件版本
  3. 取得服務索引

    • 要求方向:外掛程式 -> NuGet
    • 要求將包含:
      • 套件來源存放庫位置
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,則為服務索引
  4. 握手

    • 要求方向:NuGet <-> 外掛程式
    • 要求將包含:
      • 目前的外掛程式通訊協定版本
      • 最低支援的外掛程式通訊協定版本
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,則為交涉的通訊協定版本。 失敗會導致外掛程式終止。
  5. Initialize

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • NuGet 用戶端工具版本
      • NuGet 用戶端工具的有效語言。 如果使用,這會考慮 ForceEnglishOutput 設定。
      • 預設要求逾時,取代通訊協定預設值。
    • 回應將包含:
      • 指出作業結果的回應碼。 失敗會導致外掛程式終止。
  6. Log

    • 要求方向:外掛程式 -> NuGet
    • 要求將包含:
      • 要求的記錄層級
      • 要記錄的訊息
    • 回應將包含:
      • 指出作業結果的回應碼。
  7. 監視 NuGet 進程結束

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • NuGet進程標識碼
    • 回應將包含:
      • 指出作業結果的回應碼。
  8. 預先擷取套件

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件識別碼和版本
      • 套件來源存放庫位置
    • 回應將包含:
      • 指出作業結果的回應碼
  9. 設定認證

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 套件來源存放庫位置
      • 如果有的話,最後一個已知的套件來源用戶名稱
      • 如果有的話,則為最後一個已知的套件來源密碼
      • 如果有的話,最後一個已知的 Proxy 用戶名稱
      • 如果有的話,則為最後一個已知的 Proxy 密碼
    • 回應將包含:
      • 指出作業結果的回應碼
  10. 設定記錄層級

    • 要求方向:NuGet -> 外掛程式
    • 要求將包含:
      • 默認記錄層級
    • 回應將包含:
      • 指出作業結果的回應碼

通訊協定 2.0.0 版訊息

  1. 取得作業宣告
  • 要求方向:NuGet -> 外掛程式

    • 要求將包含:
      • 封裝來源的服務index.json
      • 套件來源存放庫位置
    • 回應將包含:
      • 指出作業結果的回應碼
      • 如果作業成功,可列舉支持的作業。 如果外掛程式不支援套件來源,外掛程式必須傳回空的一組支持作業。

    如果服務索引和套件來源為 Null,則外掛程式可以使用驗證來回答。

  1. 取得驗證認證
  • 要求方向:NuGet -> 外掛程式
  • 要求將包含:
    • URI
    • isRetry
    • NonInteractive
    • CanShowDialog
  • 回應將包含
    • 使用者名稱
    • 密碼
    • 訊息
    • 驗證類型清單
    • MessageResponseCode