無論你的套件做什麼,或包含什麼程式碼,你都會使用命令列介面(CLI)工具之一,nuget.exedotnet.exe將該功能打包成一個元件,讓其他開發者共享並使用。 若要安裝 NuGet CLI 工具,請參閱 安裝 NuGet 用戶端工具。 Visual Studio 不會自動包含 CLI 工具。
對於非 SDK 風格的專案,通常是 .NET Framework 專案,請依照本文描述的步驟建立套件。 如需快速入門,提供 Visual Studio 及
nuget.exeCLI 的逐步使用說明,請參見 Quickstart:使用 Visual Studio (.NET Framework, Windows) 建立並發佈套件。對於使用 SDK 風格格式 的 .NET Core 與 .NET Standard 專案,以及其他任何 SDK 風格專案,請參見 Create a NuGet 套件搭配 dotnet CLI。
對於從
packages.config遷移到PackageReference的專案,請使用指令msbuild -t:pack。
技術上來說,NuGet 套件是一個 ZIP 檔,將副檔名改為 .nupkg ,內容符合某些慣例。 本文詳細說明了建立符合這些慣例的套件的過程。
封裝從編譯好的程式碼(組件)、符號及其他你想以套件形式交付的檔案開始。 關於包裝流程的概述,請參見 「套件建立工作流程」。 此過程獨立於編譯或產生包含在套件中的檔案。 但你可以從專案檔案中的資訊中提取資料,讓編譯後的組合套件和套件保持同步。
這很重要
本文適用於非 SDK 風格的專案,通常是使用 Visual Studio 2017 及更新版本與 NuGet 4.0+ 的 .NET Core 與 .NET Standard 專案以外的專案。
決定要封裝的組件
大部分的一般用途套件都包含一或多個元件,其他開發人員可以在自己的專案中使用。
一般而言,最好每個 NuGet 套件都有一個元件,前提是每個元件都獨立有用。 例如,考慮以下情況,涉及一個稱為 Utilities.dll 的組裝,該組裝依賴於一個稱為 Parser.dll的組裝:
如果 Parser.dll 本身就有用,可以建立一個套件給 Utilities.dll ,一個給 Parser.dll。 這樣做讓開發者能獨立於 Utilities.dll使用 Parser.dll。
如果 Parser.dll 包含只有 Utilities.dll使用的程式碼,那麼將 Parser.dll 放在同一個套件中是可以的。 一般來說,如果你的函式庫是由多個獨立無用的組合組成,將它們合併成一個套件是可以的。
如果 Utilities.dll 也依賴 Utilities.resources.dll,而 Utilities.resources.dll 單獨用不著,那就把兩者放在同一個包裡。
資源,例如前述 Utilities.resources.dll 組裝,屬於特殊情況。 當套件安裝到專案中時,NuGet 會自動將該套件的 DLL 新增為組件參考,但不會包含名為 .resources.dll 的 DLL,因為它們被認為是本地化的衛星組件。 欲了解更多關於函式庫在地化版本的資訊,請參閱 「建立在地化 NuGet 套件」。 因此,避免對包含重要套件程式碼的檔案使用 .resources.dll 。
如果您的函式庫包含元件物件模型(COM)互操作組件,請遵循 包含 COM 互操作組件的 Create NuGet 套件中的額外指引。
.nuspec 檔案的角色和結構
當你知道要打包哪些檔案後,下一步是建立一個 .nuspec XML 檔案的套件清單。
清單:
- 描述套件的內容,並本身包含在套件中。
- 推動套件的建立,並告訴 NuGet 如何將套件安裝到專案中。 例如,清單會識別其他套件相依,讓 NuGet 在主套件安裝時也能安裝這些相依。
- 包含本節其餘部分所述的必要與可選屬性。 如需詳細資訊,包括未提及的其他性質,請參閱 .nuspec 參考資料。
清單中必須包含以下屬性:
- 套件識別碼,必須在承載該套件的圖庫中是唯一的
- 以 Major.Minor.Patch[-Suffix] 形式表示的特定版本號,其中 -Suffix 代表 預發布版本
- 主機上應顯示的套件標題 (如 nuget.org)
- 作者資訊
- 針對套件的詳細描述
以下屬性為常見的可選性:
- 釋稿說明。
- 版權資訊。
- Visual Studio 中
封裝管理員 介面的簡短說明。 - 地點識別。
- 一個專案網址。
- 授權可以是表達式或檔案形式。 該
licenseUrl物業已被棄用。 改用licensenuspec 的元資料元素 。 - 一個可讀檔案。
- 一個圖示檔案。 該
iconUrl物業已被棄用。 改用iconnuspec 的元資料元素 。 - 相依關係與參考清單。
- 協助圖庫搜尋的標籤。
以下程式碼是一個典型(但虛構)的 .nuspec 檔案,附有描述屬性的註解:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<!-- An identifier that must be unique within the hosting gallery -->
<id>Contoso.Utility.UsefulStuff</id>
<!-- A package version number that's used when resolving dependencies -->
<version>1.8.3</version>
<!-- A comma-separated list of package authors that sometimes appears directly on the gallery -->
<authors>Dejana Tesic, Rajeev Dey</authors>
<!-- A project URL that provides a link for the gallery -->
<projectUrl>http://github.com/contoso/UsefulStuff</projectUrl>
<!-- License information that's displayed on the gallery -->
<license type="expression">Apache-2.0</license>
<!-- The location of a read-me file that's displayed in the Visual Studio Package Manager UI -->
<readme>readme.md</readme>
<!-- An icon that's used in the Visual Studio Package Manager UI -->
<icon>icon.png</icon>
<!--
A property that when true, prompts the user to accept the license when
installing the package
-->
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<!-- Detailed information about a particular release -->
<releaseNotes>Bug fixes and performance improvements</releaseNotes>
<!--
A description that can be used in the Package Manager UI. The
nuget.org gallery uses information you add in the portal.
-->
<description>Core utility functions for web applications</description>
<!-- Copyright information -->
<copyright>Copyright ©2026 Contoso Corporation</copyright>
<!-- Tags that appear in the gallery and can be used for tag searches -->
<tags>web utility http json url parsing</tags>
<!-- Dependencies that are automatically installed when the package is installed -->
<dependencies>
<dependency id="Newtonsoft.Json" version="9.0" />
</dependencies>
</metadata>
<!-- A read-me Markdown file that's displayed in the Package Manager UI -->
<files>
<file src="readme.md" target="" />
<file src="icon.png" target="" />
</files>
</package>
關於宣告相依關係及指定版本號的詳細資訊,請參見 packages.config 與 套件版本管理。 你也可以在 dependency 元素上使用 include 和 exclude 屬性來指定你想在套件中包含或排除的相依資產。 欲了解更多資訊,請參閱 .nuspec 參考 - 相依元素。
因為清單包含在從清單建立的套件中,你可以透過檢視現有套件找到範例。 一個不錯的來源是你電腦上的 global-packages 資料夾。 要找到它的位置,請使用以下指令:
nuget locals -list global-packages
在知道 global-packages 資料夾的位置後,請採取以下步驟尋找清單檔案:
- 前往 global-packages 資料夾。
- 在該資料夾中,進入任何套件的子資料夾,再進入該套件任一版本的子資料夾。
- 在版本子資料夾裡,複製 .nupkg 檔案,並將副檔名改為 zip。
- 打開 .zip 檔案,檢查裡面的 .nuspec 檔案。
備註
當你從Visual Studio專案建立 .nuspec 檔案時,清單中包含的標記,套件建置時會被專案資訊取代。 欲了解更多資訊,請參閱 從 Visual Studio 專案建立 .nuspec 檔案。
建立 .nuspec 檔案
建立完整清單通常從以下方法之一產生的基本 .nuspec 檔案開始:
然後,您可以手動編輯檔案,使其描述最終套件中您想要的確切內容。
這很重要
產生的 .nuspec 檔案包含佔位符,您必須在使用指令建立套件 nuget pack 前修改這些檔位符。 如果 .nuspec 檔案包含任何佔位符,該指令就會失敗。
從慣例型工作目錄
因為 NuGet 套件是 ZIP 檔,名稱被改為 .nupkg 副檔名,通常最簡單的做法是先在本地檔案系統建立你想要的資料夾結構,然後直接從該結構建立 .nuspec 檔案。
nuget pack這個指令會自動將該資料夾結構中的所有檔案加入,但排除以句點開頭的資料夾,讓你可以保留私密檔案在同一結構中。
此方法的優點是你不必在清單中指定想包含哪些檔案,如本節後述所述。 相反地,你可以讓你的建置流程產生與套件相同的資料夾結構。 你也可以輕鬆加入其他可能不會包含在專案中的檔案:
- 應該注入目標專案的內容與原始碼
- PowerShell 腳本
- 專案中對現有組態與原始碼檔案的轉換
這些資料夾符合以下慣例:
| 資料夾 | 內容 | 套件安裝時的動作 |
|---|---|---|
| (根目錄) | 套件清單、頂層資料夾,以及可選的自述文件 (Markdown) 和圖片圖示 | 此資料夾作為標準化子資料夾(如 lib 和 build)的起點。 |
| 程式庫/<TFM> | 針對特定目標框架名稱(TFM)的程序集(.dll)、文件(.xml)及符號(.pdb)檔案 | 組件會被新增為編譯時與執行時的參考。 .xml 和 .pdb 檔案會被複製到專案資料夾中。 關於建立框架目標專屬子資料夾的資訊,請參見 Support multiple .NET versions。 |
| 參考/<TFM> | 組合語言(.dll)及符號(.pdb)檔案,用於給定的TFM | 程序集僅作為編譯時期的參考資料加入。 專案 箱 資料夾裡沒有東西被複製。 |
| 運行時間 | 架構專用組合(.dll)、符號(.pdb)及原生資源(.pri)檔案 | 僅在執行時將組件作為參考庫加入。 其他檔案則被複製到專案資料夾中。 在 /ref/<tfm> 資料夾下,應該永遠有一個對應的 TFM 特定程序集,以提供對應的編譯時程序集。 請參見 支援多個.NET版本。 |
| 內容 | 任意檔案 | 內容會被複製到專案根節點。 將 內容 資料夾視為最終取用套件的目標應用程式根目錄。 若要讓套件在應用程式的 /images 資料夾中新增影像,請將它放在套件的 content/images 資料夾中。 |
| 構建 | (3.x+) Microsoft Build 引擎(MSBuild).targets 及 .props 檔案 | 這些檔案會自動插入專案中。 |
| buildMultiTargeting | (4.0+) MSBuild .targets 與 .props 檔案用於跨框架目標鎖定 | 這些檔案會自動插入專案中。 |
| buildTransitive | (5.0+) MSBuild .targets 與 .props 檔案,可傳遞至任何消耗型專案 | 這些檔案會自動插入專案中。 請參閱功能頁面。 |
| 工具 | 可從 封裝管理員 主控台存取的 PowerShell 腳本與程式 |
tools 資料夾僅在 封裝管理員 控制台的 PATH 環境變數中加入。 它 不會 被添加到 MSBuild 用於建置專案的 PATH 值中。 |
由於你的資料夾結構可以包含多個目標框架的組合語言,因此當你建立支援多個框架的套件時,這種方法是必要的。
當你建立了想要的資料夾結構後,在該資料夾執行以下指令來建立 .nuspec 檔案:
nuget spec
產生的 .nuspec 檔案中沒有明確引用資料夾結構中的檔案。 NuGet 在建立套件時會自動包含所有檔案。 不過,您仍然需要編輯資訊清單其他部分的佔位符值。
從元件 DLL
在從組合語言建立套件的基本情況下,你可以使用以下指令從組合語言中的元資料產生 .nuspec 檔案:
nuget spec <assembly-name>.dll
使用此表單可將資訊清單中的幾個預留位置,以元件中特定的值取而代之。 例如, <id> 內容會設定為組合名稱,並 <version> 設定為組合版本。 然而,清單中其他屬性的值在組裝中並不相符。 執行指令後,這些屬性仍然包含佔位符。
來自 Visual Studio 專案
從 .csproj 或 .vbproj 檔案建立 .nuspec 檔案很方便,因為專案中安裝的其他套件會自動被引用為相依。 要從專案檔案建立清單,請在包含專案檔案的資料夾中使用以下指令:
# Use in a folder that contains a project file, such as <project-name>.csproj or <project-name>.vbproj.
nuget spec
產生的 <project-name.nuspec> 檔案包含標記,這些標記在打包時會被專案的值替換,並引用已安裝的其他套件。
如果你有套件相依性需要包含在 .nuspec 中,請改用 nuget pack。 接著從產生的 .nupkg 檔案中取得 .nuspec 檔案。 例如,請使用以下指令:
# Use in a folder that contains a project file, such as <project-name>.csproj or <project-name>.vbproj.
nuget pack myproject.csproj
記號由專案屬性兩側的 $ 符號隔開。 例如, <id> 以這種方式產生的清單中的價值通常如下:
<id>$id$</id>
此符號會在封裝時被專案檔中的AssemblyName值取代。 關於專案值與 .nuspec 檔案標記的精確對應,請參見替換標記。
代幣可以讓你在更新專案時,不用再更新像是 .nuspec 檔案中的版本號這類關鍵值。 但你也可以用字面值替換代幣。
當你從Visual Studio專案開始工作時,還有多種額外的封裝選項,詳見本文後面的 Run nuget 套件以產生 .nupkg 檔案。
解決方案層級套件
僅適用於 NuGet 2.x 無法在 NuGet 3.0+ 中使用。
NuGet 2.x 支援解決方案層級套件的概念,該套件可安裝工具或額外指令給 封裝管理員 Console(tools 資料夾的內容),但不會為解決方案中的任何專案新增參考、內容或建置自訂。 這類套件的直接 函式庫、 內容或 建置 資料夾中沒有任何檔案,且其相依性在各自的 函式庫、 內容或 建置 資料夾中也沒有檔案。
NuGet 會在 .nuget 資料夾中的 packages.config 檔案中追蹤已安裝的解決方案層級套件,而非專案的 packages.config 檔案。
從預設值的新檔案開始
以下指令建立帶有佔位符的預設清單,幫助你確保從正確的檔案結構開始:
nuget spec [<package-name>]
若省略 <package-name>,所得檔案將命名為 Package.nuspec。 如果你提供像 Contoso.Utility.UsefulStuff這樣的名稱,檔案名稱為 Contoso.Utility.UsefulStuff.nuspec。
產生的 .nuspec 檔案包含數值的佔位符,例如 projectUrl。 在使用該檔案建立最終 .nupkg 檔案之前,請先將佔位符替換成適當的值。
選擇唯一的套件識別碼並設定版本號碼
套件識別碼(<id> 元素)和版本號(<version> 元素)是清單中最重要的兩個值,因為它們能唯一識別套件中所包含的精確程式碼。
套件識別碼的最佳實務
-
唯一性:識別碼必須在承載套件的圖庫中唯一,例如 nuget.org。在決定識別碼之前,請先搜尋相關相簿,確認該名稱是否已經在使用中。 為了避免衝突,一個好的模式是使用您的公司名稱作為識別碼的第一部分,例如
Contoso。 -
類命名空間名稱:採用類似.NET命名空間的模式,使用點符號代替連字號。 例如,使用
Contoso.Utility.UsefulStuff而不是Contoso-Utility-UsefulStuff或Contoso_Utility_UsefulStuff。 當套件識別碼符合程式碼中使用的命名空間時,取用者也發現它很有幫助。 -
範例套件:如果你製作了一個範例程式碼套件,示範如何使用另一個套件,請
.Sample在識別碼後加上後綴,如Contoso.Utility.UsefulStuff.Sample。 此類範例套件依賴於其展示如何使用的套件。 建立範例套件時,請使用先前描述的基於慣例的工作目錄方法。 在 content 資料夾中,將範例程式碼整理在一個名為 \Samples\<identifier> 的資料夾中,例如 \Samples\Contoso.Utility.Utility.UsefulStuff.Sample。
套件版本的最佳實務
- 一般來說,將套件的版本設定為與函式庫相符。 此指引建議但非強制。 當你將套件限制為單一組裝體時,這個做法就很簡單,就像前面在 「決定要打包哪些組裝體」中所描述的那樣。 一般來說,請記得 NuGet 本身處理的是套件版本來解決相依關係,而不是組合語言版本。
- 使用非標準版本方案時,請考慮套件 版本管理中說明的 NuGet 版本管理規則。
如需其他有助於理解版本控制的資源,請參閱以下一系列簡短的部落格文章:
新增一個README檔案和其他檔案
若要直接指定要包含在套件中的檔案,請使用 <files>.nuspec 檔案中的節點,該節點 緊接著 標籤 <metadata> :
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<!-- ... -->
</metadata>
<files>
<!-- Add files from an arbitrary folder that's not necessarily in the project. -->
<file src="..\..\SomeRoot\**\*.*" target="" />
</files>
</package>
小提示
使用慣例式的工作目錄方法時,你可以將 readme.md 檔案放在套件根目錄,其他內容則放在 content 資料夾。 資訊清單中不需要任何 <file> 元素。
若要在套件中包含可讀檔案,請使用 readme 元資料元素指定該可讀檔案的目標路徑。 同時 file 使用元資料元素指定 read-me 檔案的來源路徑與目標資料夾。 如需詳細資訊,請參閱readme。
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<!-- ... -->
<readme>docs\readme.md</readme>
<!-- ... -->
</metadata>
<files>
<!-- Add a read-me file. -->
<file src="..\readme.md" target="docs\" />
</files>
</package>
Visual Studio 會在 封裝管理員 介面中顯示 read-me 檔案的內容。 例如,以下截圖展示了該 HtmlAgilityPack 套件的 read-me 檔案:
備註
如果你在 <files> 檔案中加入空節點,NuGet 會包含套件中 lib 資料夾的內容,但不會包含其他內容。
在套件中包含 MSBuild props 和目標項目
在某些情況下,你可能想為佔用套件的專案新增自訂建置目標或屬性,例如在建置過程中執行自訂工具或程序。 欲了解更多自訂建置目標與屬性的資訊,請參閱 MSBuild 套件中的 .props 與 .targets。
在專案的<資料夾中建立 < 或 >package-id.props 檔案,例如 Contoso.Utility.Utility.UsefulStuff.targets。
然後在 .nuspec 檔案的 <files> 節點中,引用這些檔案:
<?xml version="1.0"?>
<package >
<metadata minClientVersion="2.5">
<!-- ... -->
</metadata>
<files>
<!-- In the package build folder, include everything that's in the local build folder. -->
<file src="build\**" target="build" />
<!-- Other files -->
<!-- ... -->
</files>
</package>
當套件加入專案時,NuGet 會自動包含這些屬性與目標。
執行 nuget pack 以產生 .nupkg 檔案
當您使用組件或基於慣例的工作目錄時,請透過執行 nuget pack 命令並結合您的 .nuspec 檔案來建立套件。 在以下指令中,請將你專案名稱替換 <project-name> 為:
nuget pack <project-name>.nuspec
使用Visual Studio專案時,請用專案檔案執行 nuget pack。 此指令會自動載入專案的 .nuspec 檔案,並將其中所有標記替換為專案檔案中對應的值:
nuget pack <project-name>.csproj
備註
若要替換令牌,必須直接使用專案檔案,因為專案是令牌值的來源。 如果使用nuget pack與.nuspec檔案,權杖替換將無法成功。
在所有情況下,nuget pack 會排除以點開頭的資料夾,例如 .git 或 .hg。
NuGet 會指示 .nuspec 檔案中是否有需要修正的錯誤,例如清單中的佔位值需要更新。
成功後nuget pack,您會獲得一個.nupkg檔案,您可以按照發佈 NuGet 套件中的說明將其發佈到合適的圖庫。
小提示
在建立套件之後檢查套件的實用方法是在 [套件總管 ] 工具中開啟它。 此工具提供包裹內容及其清單的圖形視圖。 你也可以將產生的 .nupkg 檔案重新命名為 .zip 檔案,直接探索其內容。
其他選項
您可以使用各種命令列參數 nuget pack 來排除檔案、覆寫資訊清單中的版本號碼,以及變更輸出資料夾等功能。 完整清單請參見 pack 指令(NuGet CLI)。
以下是 Visual Studio 專案中常見的幾個選項:
參考專案:如果專案參考其他專案,您可以使用以下
-IncludeReferencedProjects選項將參考專案新增為套件的一部分,或新增為相依性:nuget pack MyProject.csproj -IncludeReferencedProjects這個包含過程是遞迴的。 例如,如果 MyProject.csproj 參考專案 B 和 C,而這些專案參考 D、E、F 時,套件中會包含 B、C、D、E、F 的檔案。
如果一個被參考的專案包含自己的 .nuspec 檔案,NuGet 會將該參考專案作為相依項目加入。 您需要分別封裝和發佈該專案。
建置設定:預設情況下,NuGet 使用專案檔案中設定的預設建置配置,通常是
Debug。 若要從不同的建置配置打包檔案,例如Release,請使用-properties以下設定中的選項:nuget pack MyProject.csproj -properties Configuration=Release符號:若要包含讓使用者能在除錯器中逐步檢視套件程式碼的符號,請使用
-Symbolsand-SymbolPackageFormat選項。 對-SymbolPackageFormat選項,指定格式為snupkg:nuget pack MyProject.csproj -symbols -SymbolPackageFormat snupkg
測試套件安裝
在發佈套件之前,通常你會想測試將套件安裝到專案中的過程。 測試有助於確保所有必要的檔案最終都位於專案的正確位置。
你可以在Visual Studio或命令列手動測試安裝,使用標準的 package 安裝步驟。
自動化測試時,你可以使用以下基本流程:
- 把 .nupkg 檔案複製到本地資料夾。
- 用指令
nuget sources add -name <name> -source <path>將資料夾加入你的套件來源。 欲了解更多資訊,請參閱 sources 指令(NuGet CLI)。 你只需要在任何一台電腦上設定一次本地來源。 - 從該來源安裝套件,使用
nuget install <package-ID> -source <name>。 在此指令中,<name>應與您在nuget sources指令中使用的來源名稱相符。 指定來源會讓 NuGet 只從該來源安裝套件。 - 檢查您的檔案系統,以檢查檔案是否已正確安裝。
相關內容
當你建立一個套件( .nupkg 檔案)後,你可以將其發佈到你選擇的畫廊。 欲了解更多資訊,請參閱發佈 NuGet 套件。
你也可以擴充套件的功能,或支援其他情境。 如需詳細資訊,請參閱下列文章:
關於其他需要注意的套件類型,請參閱以下文章: