在 NuGet 4.8+ 中,已新增對跨平台外掛程式的支援。 這是透過建置新的外掛程式擴充性模型來達成,該模型必須符合一組嚴格的作業規則。 外掛程式是獨立可執行檔(可在 .NET Core 世界中執行),NuGet 用戶端會在個別程序中啟動。 這是一個真正的寫一次,處處執行的插件。 它將使用所有 NuGet 用戶端工具。 外掛程式可以使用任何程式設計語言撰寫,但最簡單的外掛程式開發和安裝體驗是 .NET。 NuGet 用戶端與外掛程式之間的版本化通訊協定已定義。 在啟動交握期間,兩個程序會協商協定版本。
運作方式
高階工作流程可描述如下:
- NuGet 會探索可用的外掛程式。
- 適用時,NuGet 會依優先順序逐一逐一查看外掛程式,並逐一啟動外掛程式。
- NuGet 會使用可服務要求的第一個外掛程式。
- 不再需要外掛程式時,這些外掛程式將會關閉。
一般外掛程式需求
目前的通訊協定版本是 2.0.0。 在此版本中,需求如下:
- 支援 NuGet 用戶端工具目前安全性內容下的無狀態啟動。 例如,NuGet 用戶端工具不會在稍後所述的插件協定之外執行提升權限或其他初始化。
- 除非明確指定,否則為非互動式。
- 遵守協商的插件協定版本。
- 在合理的期間內回應所有要求。
- 接受任何進行中作業的取消要求。
從 PATH 環境變數探索到的外掛程式(例如透過 安裝 dotnet tool),此外必須符合檔案名模式 nuget-plugin-*。
部分 nuget-plugin- 必須完全以小寫字母撰寫。
NuGet 6.12 (MSBuild 17.12 和 .NET SDK 9.0.100)和更早版本也需要在 Windows 上簽署 Authenticode 的外掛程式。
下列規格會更詳細地說明技術規格:
用戶端 - 外掛程式互動
NuGet 用戶端工具和外掛程式會透過標準數據流與 JSON 通訊(stdin、stdout、stderr)。 所有數據都必須經過UTF-8編碼。 外掛程式會以自變數 「-Plugin」 啟動。 如果使用者直接啟動沒有此參數的外掛程式可執行檔,外掛程式可以提供提示性訊息,而不是等待通訊協定交握。 通訊協定交握逾時為5秒。 外掛程式應該儘可能快速地完成設定。 NuGet 用戶端工具會傳入 NuGet 來源的服務索引,以查詢外掛程式支援的作業。 外掛程式可以使用服務索引來檢查支援的服務類型是否存在。
NuGet 用戶端工具和外掛程式之間的通訊是雙向的。 每個請求都有5秒的超時。 如果作業應該花費較長的時間,個別進程應該會傳送進度訊息,以防止要求逾時。在閑置 1 分鐘之後,外掛程式就會被視為閑置且已關閉。
外掛程式安裝和探索
NuGet 會從慣例型目錄結構搜尋外掛程式,並掃描PATH環境變數。
以慣例為基礎的探索
CI/CD 情境和進階使用者可以使用環境變數來改變行為。
使用環境變數時,只允許絕對路徑。 請注意, NUGET_NETFX_PLUGIN_PATHS 和 NUGET_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 外掛程式。
| Framework | 根節點發現位置 | 使用者是 |
|---|---|---|
| .NET 核心 | %UserProfile%/.nuget/plugins/netcore |
dotnet CLI(命令列介面) |
| .NET Framework | %UserProfile%/.nuget/plugins/netfx |
MSBuild、NuGet.exe、Visual Studio |
每個外掛程式都應該安裝在自己的資料夾中。 外掛程式進入點會是已安裝資料夾的名稱,具有 .NET Core 的 .dll 擴展名,以及 .NET Framework 的 .exe 擴展名。
.nuget
plugins
netfx
myPlugin
myPlugin.exe
nuget.protocol.dll
...
netcore
myPlugin
myPlugin.dll
nuget.protocol.dll
...
PATH 探索
從 NuGet 6.13 開始,NuGet 會搜尋 PATH 環境變數中提供的每個目錄,以尋找符合模式 nuget-plugin-*的檔案。
模式比對會區分大小寫,而且 nuget-plugin- 必須完全以小寫字母撰寫。
在 Windows 上,檔案必須具有 .exe 或 .bat 擴展名。
在 Linux 和 Mac 上,檔案必須設定可執行檔位。
這可讓 NuGet 外掛程式透過 dotnet tool 命令、WinGet、Linux 發行版的套件管理員或任何其他方法安裝,以將可執行檔放在使用者的 PATH 上。
這也允許以任何程式設計語言撰寫 NuGet 外掛程式(先前的 Linux 和 Mac 外掛程式必須以 .NET 撰寫)。
我們建議您在 .NET 中開發外掛程式,以便您可以使用 NuGet.Protocol 套件 來避免需要撰寫 json RPC 程式代碼,並允許客戶透過 dotnet package search nuget-plugin探索您的外掛程式。
支援的作業
新的外掛程式通訊協定支援兩項作業。
| 作業名稱 | 最低通訊協定版本 | 最低 NuGet 用戶端版本 |
|---|---|---|
| 下載套件 | 1.0.0 | 4.3.0 |
| 驗證 | 2.0.0 | 4.8.0 |
在正確的運行時間下執行外掛程式
針對 dotnet.exe 案例中的 NuGet,外掛程式必須能夠在 dotnet.exe的特定運行時間下執行。 負責確保使用相容的 dotnet.exe/plugin 組合的是外掛程式提供者和使用者。 例如,在 2.0 執行時間下 dotnet.exe 嘗試使用針對 2.1 運行時間撰寫的外掛程式時,使用者位置外掛程式可能會發生潛在問題。
功能快取
外掛程式的安全性驗證和具現化成本很高。 下載作業會比驗證作業更頻繁,不過平均 NuGet 使用者可能只有驗證外掛程式。 為了改善使用者體驗,NuGet 會快取指定請求的操作聲明。 此快取是針對每個外掛程式而設,且外掛程式密鑰為外掛程式路徑,此功能快取的到期日為30天。
快取位於%LocalAppData%/NuGet/plugins-cache,可以被環境變數NUGET_PLUGINS_CACHE_PATH覆寫。
若要清除此 快取,可以使用 plugins-cache 選項來執行 locals 指令。
本地 all 選項現在也會刪除插件快取。
通訊協定訊息索引
通訊協定 1.0.0 版 訊息:
關閉
- 要求方向:NuGet -> 外掛程式
- 該請求將不包含任何有效負載
- 沒有預期的回應。 適當的回應是讓外掛程式立即退出。
複製套件中的檔案
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件識別碼和版本
- 套件來源存放庫位置
- 目的地目錄路徑
- 封裝中要複製到目的地目錄路徑的檔案可列舉
- 回應將包含:
- 指出作業結果的回應碼
- 成功作業後,目的地目錄中複製檔案的完整路徑可以列舉出。
複製套件檔案 (.nupkg)
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件識別碼和版本
- 套件來源存放庫位置
- 目的地檔案路徑
- 回應將包含:
- 指出作業結果的回應碼
取得認證
- 請求指示:外掛程式 -> NuGet
- 要求將包含:
- 套件來源存放庫位置
- 使用目前認證從套件來源存放庫取得的 HTTP 狀態代碼
- 回應將包含:
- 指出作業結果的回應碼
- 用戶名稱(如果有)
- 密碼(如果有)
取得套件中的檔案
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件識別碼和版本
- 套件來源存放庫位置
- 回應將包含:
- 指出作業結果的回應碼
- 如果作業成功,可以列舉封裝中的檔案路徑
取得操作聲明
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 用於套件來源的服務 index.json
- 套件來源存放庫位置
- 回應將包含:
- 指出作業結果的回應碼
- 如果作業成功,可列舉支持的作業(例如:套件下載)。 如果外掛程式不支援套件來源,外掛程式必須傳回空的一組支持作業。
備註
此訊息已在 2.0.0 版中更新。 它位於用戶端上,以保留回溯相容性。
取得套件哈希
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件識別碼和版本
- 套件來源存放庫位置
- 哈希演算法
- 回應將包含:
- 指出作業結果的回應碼
- 如果操作成功,則使用要求的哈希演算法生成套件檔案的哈希值。
取得套件版本
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件識別碼
- 套件來源存放庫位置
- 回應將包含:
- 指出作業結果的回應碼
- 如果作業成功,則會返回一個可列舉的套件版本集合。
取得服務索引
- 請求指示:外掛程式 -> NuGet
- 要求將包含:
- 套件來源存放庫位置
- 回應將包含:
- 指出作業結果的回應碼
- 作業成功時的服務索引
握手
- 要求方向:NuGet <-> 外掛程式
- 要求將包含:
- 目前的外掛程式通訊協定版本
- 最低支援的外掛程式通訊協定版本
- 回應將包含:
- 指出作業結果的回應碼
- 如果作業成功,則為交涉的通訊協定版本。 失敗會導致外掛程式終止。
初始化
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- NuGet 用戶端工具版本
- NuGet 用戶端工具的有效語言。 如果使用此功能,則會考慮 ForceEnglishOutput 設定。
- 預設的要求逾時設定,其預設值會取代通訊協定的預設值。
- 回應將包含:
- 指出作業結果的回應碼。 失敗會導致外掛程式終止。
日誌
- 請求指示:外掛程式 -> NuGet
- 要求將包含:
- 要求的記錄層級
- 要記錄的訊息
- 回應將包含:
- 指出作業結果的回應碼。
監視 NuGet 程序結束
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- NuGet進程標識碼
- 回應將包含:
- 指出作業結果的回應碼。
預先擷取套件
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件識別碼和版本
- 套件來源存放庫位置
- 回應將包含:
- 指出作業結果的回應碼
設定認證
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 套件來源存放庫位置
- 最後已知的套件來源用戶名稱(如果有的話)
- 如果有的話,則為最後一個已知的套件來源密碼
- 最後一個已知的代理用戶名稱,如果有的話
- 如果有的話,則為最後一個已知的 Proxy 密碼
- 回應將包含:
- 指出作業結果的回應碼
設定記錄層級
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 默認記錄層級
- 回應將包含:
- 指出作業結果的回應碼
通訊協定 2.0.0 版 訊息
- 取得作業聲明
要求方向:NuGet -> 外掛程式
- 要求將包含:
- 用於套件來源的服務 index.json
- 套件來源存放庫位置
- 回應將包含:
- 指出作業結果的回應碼
- 如果作業成功,可列舉支持的作業。 如果外掛程式不支援套件來源,外掛程式必須傳回空的一組支持作業。
如果服務索引和套件來源為 Null,則外掛程式可以使用驗證來回答。
- 要求將包含:
- 取得驗證認證
- 要求方向:NuGet -> 外掛程式
- 要求將包含:
- 統一資源識別碼 (URI)
- 是否重試
- 非互動式
- CanShowDialog
- 回應將包含
- 用戶名稱
- 密碼
- 訊息
- 驗證類型清單
- MessageResponseCode