共用方式為


使用 nuget.exe CLI 建立套件

無論你的套件做什麼,或包含什麼程式碼,你都會使用命令列介面(CLI)工具之一,nuget.exedotnet.exe將該功能打包成一個元件,讓其他開發者共享並使用。 若要安裝 NuGet CLI 工具,請參閱 安裝 NuGet 用戶端工具。 Visual Studio 不會自動包含 CLI 工具。

技術上來說,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 物業已被棄用。 改用 license nuspec 的元資料元素
  • 一個可讀檔案。
  • 一個圖示檔案。 該 iconUrl 物業已被棄用。 改用 icon nuspec 的元資料元素
  • 相依關係與參考清單。
  • 協助圖庫搜尋的標籤。

以下程式碼是一個典型(但虛構)的 .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 元素上使用 includeexclude 屬性來指定你想在套件中包含或排除的相依資產。 欲了解更多資訊,請參閱 .nuspec 參考 - 相依元素

因為清單包含在從清單建立的套件中,你可以透過檢視現有套件找到範例。 一個不錯的來源是你電腦上的 global-packages 資料夾。 要找到它的位置,請使用以下指令:

nuget locals -list global-packages

在知道 global-packages 資料夾的位置後,請採取以下步驟尋找清單檔案:

  1. 前往 global-packages 資料夾。
  2. 在該資料夾中,進入任何套件的子資料夾,再進入該套件任一版本的子資料夾。
  3. 在版本子資料夾裡,複製 .nupkg 檔案,並將副檔名改為 zip
  4. 打開 .zip 檔案,檢查裡面的 .nuspec 檔案。

備註

當你從Visual Studio專案建立 .nuspec 檔案時,清單中包含的標記,套件建置時會被專案資訊取代。 欲了解更多資訊,請參閱 從 Visual Studio 專案建立 .nuspec 檔案

建立 .nuspec 檔案

建立完整清單通常從以下方法之一產生的基本 .nuspec 檔案開始:

然後,您可以手動編輯檔案,使其描述最終套件中您想要的確切內容。

這很重要

產生的 .nuspec 檔案包含佔位符,您必須在使用指令建立套件 nuget pack 前修改這些檔位符。 如果 .nuspec 檔案包含任何佔位符,該指令就會失敗。

從慣例型工作目錄

因為 NuGet 套件是 ZIP 檔,名稱被改為 .nupkg 副檔名,通常最簡單的做法是先在本地檔案系統建立你想要的資料夾結構,然後直接從該結構建立 .nuspec 檔案。 nuget pack這個指令會自動將該資料夾結構中的所有檔案加入,但排除以句點開頭的資料夾,讓你可以保留私密檔案在同一結構中。

此方法的優點是你不必在清單中指定想包含哪些檔案,如本節後述所述。 相反地,你可以讓你的建置流程產生與套件相同的資料夾結構。 你也可以輕鬆加入其他可能不會包含在專案中的檔案:

  • 應該注入目標專案的內容與原始碼
  • PowerShell 腳本
  • 專案中對現有組態與原始碼檔案的轉換

這些資料夾符合以下慣例:

資料夾 內容 套件安裝時的動作
(根目錄) 套件清單、頂層資料夾,以及可選的自述文件 (Markdown) 和圖片圖示 此資料夾作為標準化子資料夾(如 libbuild)的起點。
程式庫/<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-UsefulStuffContoso_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 檔案:

Visual Studio 封裝管理員 使用者介面截圖,顯示套件詳細資訊窗格。README 標籤描述此套件的 HTML 解析能力。

備註

如果你在 <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
    
  • 符號:若要包含讓使用者能在除錯器中逐步檢視套件程式碼的符號,請使用 -Symbols and -SymbolPackageFormat 選項。 對 -SymbolPackageFormat 選項,指定格式為 snupkg

    nuget pack MyProject.csproj -symbols -SymbolPackageFormat snupkg
    

測試套件安裝

在發佈套件之前,通常你會想測試將套件安裝到專案中的過程。 測試有助於確保所有必要的檔案最終都位於專案的正確位置。

你可以在Visual Studio或命令列手動測試安裝,使用標準的 package 安裝步驟

自動化測試時,你可以使用以下基本流程:

  1. .nupkg 檔案複製到本地資料夾。
  2. 用指令 nuget sources add -name <name> -source <path> 將資料夾加入你的套件來源。 欲了解更多資訊,請參閱 sources 指令(NuGet CLI)。 你只需要在任何一台電腦上設定一次本地來源。
  3. 從該來源安裝套件,使用 nuget install <package-ID> -source <name>。 在此指令中,<name> 應與您在 nuget sources 指令中使用的來源名稱相符。 指定來源會讓 NuGet 只從該來源安裝套件。
  4. 檢查您的檔案系統,以檢查檔案是否已正確安裝。

當你建立一個套件( .nupkg 檔案)後,你可以將其發佈到你選擇的畫廊。 欲了解更多資訊,請參閱發佈 NuGet 套件。

你也可以擴充套件的功能,或支援其他情境。 如需詳細資訊,請參閱下列文章:

關於其他需要注意的套件類型,請參閱以下文章: