什麼是Nuget
NuGet是Microsoft開發平台的程式集包管理器,它由用戶端工具和服務端站點組成,用戶端工具提供給使用者管理和安裝/解除安裝軟體程式包,以及打包和釋出程式包到NuGet服務端站點等功能,服務端站點存儲已經發行的軟體包,并為NuGet用戶端軟體包庫提供服務,使軟體包共享給其他的開發者。
适用于任何現代開發平台的基本工具可充當一種機制,通過這種機制,開發人員可以建立、共享和使用有用的代碼。通常,此類代碼捆綁到“包”中,其中包含編譯的代碼(如DLL)以及在使用這些包的項目中所需的其他内容。
對于.NET(包括.NET Core),共享代碼的Microsoft支援的機制則為NuGet ,其定義如何建立、托管和使用面向.NET的包,并針對每個角色提供适用工具。
簡單來說,NuGet 包是具有
.nupkg
擴充的單個ZIP檔案,此擴充包含編譯代碼(Dll)、與該代碼相關的其他檔案以及描述性清單(包含包版本号等資訊)。 使用代碼的開發人員共享建立包,并将其釋出到公用或專用主機。 包使用者從适合的主機擷取這些包,将它們添加到項目,然後在其項目代碼中調用包的功能。 随後,NuGet自身負責處理所有中間詳細資訊。
由于NuGet支援公用
nuget.org
主機旁邊的專用主機,是以,可以使用NuGet包來共享組織或工作組專用的代碼。 此外,你還可以使用NuGet包作為一種便捷的方式,将自己的代碼用于除你自己項目之外的任何其他項目。 簡而言之,NuGet包是可共享的代碼單元,但不需要暗示任何特定的共享方式。
識别項目格式
NuGet适用于所有.NET項目。但是,項目格式(SDK樣式或非SDK樣式)決定了使用和建立NuGet包所需的一些工具和方法。SDK樣式的項目使用SDK屬性。确定項目類型非常重要,因為用于使用和建立NuGet包的方法和工具都依賴于項目格式。對于非SDK樣式的項目,方法和工具還取決于項目是否遷移到 PackageReference
格式。
項目類型 | 預設項目格式 | CLI工具 |
---|---|---|
.NET Standard | SDK樣式 | dotnet CLI |
.NET Core | SDK樣式 | dotnet CLI |
.NET Framework | 非SDK樣式 | nuget.exe CLI |
手動識别
使用Visual Studio Code打開
*.csproj
,如果
Project
節點,存在屬性
Sdk
基本上就是SDK樣式的。
SDK樣式示例
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
非SDK樣式示例
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
差異點
在
非SDK樣式
項目檔案夾,我們發現,它會有一個
Properties
檔案夾,裡面有個我們熟知的
AssemblyInfo.cs
記錄了這個項目的資訊。
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有關程式集的一般資訊由以下
// 控制。更改這些特性值可修改
// 與程式集關聯的資訊。
[assembly: AssemblyTitle("ExampleWinforms")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ExampleWinforms")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 設定為 false 會使此程式集中的類型
//對 COM 元件不可見。如果需要從 COM 通路此程式集中的類型
//請将此類型的 ComVisible 特性設定為 true。
[assembly: ComVisible(false)]
// 如果此項目向 COM 公開,則下列 GUID 用于類型庫的 ID
[assembly: Guid("3f148d75-9dd3-4a79-b72d-a530b0bcbc7f")]
// 程式集的版本資訊由下列四個值組成:
//
// 主版本
// 次版本
// 生成号
// 修訂号
//
//可以指定所有這些值,也可以使用“生成号”和“修訂号”的預設值
//通過使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
而在
SDK樣式
項目檔案夾,并不存在
Properties
檔案夾,項目資訊是直接記錄在
*.csproj
中的。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Description>測試</Description>
<Copyright>版權說明</Copyright>
<PackageProjectUrl>https://www.baidu.com</PackageProjectUrl>
<AssemblyVersion>1.0.0</AssemblyVersion>
<FileVersion>1.0.0</FileVersion>
<PackageReleaseNotes>發行說明</PackageReleaseNotes>
<RepositoryUrl>git.xxxxxxxxxxxxxxxxxxxxxx</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Title>ExampleWinFormsApp</Title>
<PackageId>ExampleWinFormsApp</PackageId>
<Version>1.0.0</Version>
<Authors>TaylorShi</Authors>
<Company>TaylorShi Inc.</Company>
</PropertyGroup>
</Project>
非SDK樣式項目打包
對于較為傳統的.Net framework的項目,它屬于非SDK樣式項目,是以對應的打包工具就是
nuget.exe
擷取Nuget.exe
NuGet.exe 5.0及更高版本需要 .NET Framework 4.7.2
或更高版本才能執行。
直接從
nuget.org
官方下載下傳一個即可。
- nuget.exe
建議是丢
C:\Windows
目錄即可,省去配置什麼環境變量。
Linux下安裝Nuget
sudo apt install mono-runtime
先安裝Mono 4.4.2+版本,然後執行如下指令:
sudo curl -o /usr/local/bin/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
編輯
~/.bash_aliases
或者
~/.bash_profile
,追加如下别名。
sudo vim ~/.bash_aliases
# Create as alias for nuget
alias nuget="mono /usr/local/bin/nuget.exe"
重新進入一次Shell,然後試試
nuget ?
來驗證安裝。
自我更新Nuget.exe
如果你之前已經安裝過它,還可以調用它自己的指令來更新它,因為前面我們放到
C:\Windows
目錄,是以這裡需要用管理者運作Windows Terminal。
nuget update -self
準備項目屬性
對非SDK樣式項目來說,它的項目屬性資訊是在
項目
-
屬性
-
程式集資訊
對話框中設定的,對應的檔案是
.\Properties\AssemblyInfo.cs
把這裡面能填的資訊都填下,程式集版本和檔案版本建議保持一緻,等下會作為Nuget包的版本号,前三位就行,最後一位可以是0。
建立Nuget初始清單
在目前這個
.csproj
目錄,執行如下指令:
nuget spec
它會針對
.csproj
這個項目生成一個初始清單,字尾為
*.nuspec
。
編輯補充初始清單
接下來我們可以使用Visual Studio Code,它剛開始的内容差不多是這樣:
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<!-- <icon>icon.png</icon> -->
<projectUrl>http://project_url_here_or_delete_this_line/</projectUrl>
<description>$description$</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>$copyright$</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
</package>
這裡面,有些如果有就填,沒有的話建議删除掉,比如:
-
,将包上傳到projectUrl
時,字段nuget.org
限制為4000個字元,如果有Github或者官網建議填下。projectUrl
-
,将包上傳到releaseNotes
時,字段nuget.org
限制為35,000個字元。releaseNotes
-
,這個建議填一填,友善根據關鍵詞搜尋到。tags
接下來,我們可以給它弄個圖示,這樣好看點。
首先我們需要準備一個圖示檔案,比如就叫
icon.png
,把它放到
.csproj
目錄,官方建議是128x128的PNG或者JPEG格式,體積小于1MB。
然後我們需要聲明這個圖示File檔案,比如:
<files>
<file src=".\icon.png" target="images\" />
</files>
這裡
src
就填相對目錄就可以了,這個
target
其實有點像個命名空間,意味着這個png挂在
images\
下面了,是以在
<icon>
那裡應該寫成:
<icon>images\icon.png</icon>
如果你想要Nuget.org上呈現更精彩格式的說明,也可以内置一個markdown進來,先準備一個名為
readme.md
的檔案,裡面先随便寫點。
然後以檔案形式加進來
<files>
<file src=".\readme.md" target="docs\" />
</files>
以
readme
節點添加進來
<readme>docs\readme.md</readme>
最終效果:
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<icon>images\icon.png</icon>
<readme>docs\readme.md</readme>
<projectUrl>https://www.nuget.org/packages?q=Microsoft.Extensions.Logging</projectUrl>
<description>$description$</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>$copyright$</copyright>
<tags>Microsoft TestPackage</tags>
</metadata>
<files>
<file src=".\icon.png" target="images\" />
<file src=".\readme.md" target="docs\" />
</files>
</package>
生成Nuget包
在目前這個
.csproj
目錄,執行如下指令,它就會根據我們剛才
.nuspec
和
\Properties\AssemblyInfo.cs
的資訊結合起來,形成我們要的Nuget包。
nuget pack
最終效果有沒有達到預期,我們可以用離線Nuget包源來驗證下就知道了,方式後面會介紹。
SDK樣式項目打包
擷取DotNet CLI
其實這個你裝了DotNet Core SDK的時候已經自帶了,可以執行指令驗證下:
dotnet --version
準備打包資訊
建立一個.Net Standard的類庫項目,并且添加到解決方案中:
dotnet new classlib --framework "netstandard2.0" -o netStandardLibrary
dotnet sln add .\netStandardLibrary\netStandardLibrary.csproj
對SDK風格的項目來說,一切都簡單了,打包資訊直接在
.csproj
檔案中,預設它可以是這樣子:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
接下來隻需要在
PropertyGroup
節點中來添加打包所需的資訊就是了。
<PackageId>netStandardLibrary</PackageId>
<Version>1.0.0</Version>
<Authors>Taylor</Authors>
<Company>Taylor Inc.</Company>
甚至還可以添加開關配置,這樣它預設就會生成Nuget包
<PropertyGroup>
<PackRelease>true</PackRelease>
</PropertyGroup>
生成Nuget包
同樣的,還是在
.csproj
目錄,直接執行Dotnet CLI的指令即可:
dotnet pack -c Release
這時候在
.\bin\Release\netStandardLibrary.1.0.0.nupkg
就得到這個檔案了。
釋出到Nuget.org
擷取Nuget.org密鑰
首先你需要準備一個微軟賬号,然後使用這個賬号來授權登入https://www.nuget.org即可,期間會讓你選一個名字注冊。
然後前往賬号菜單下的
API Keys
頁面。
點選
Create
按鈕建立一個新的授權密鑰
其中
Key Name
随便填,但是
Glob Pattern
那裡可以填
*
,代表沒有限制,過期時間目前最長也就
365
天,然後點選
Create
按鈕即可。
建立成功之後,就可以在
Manage
清單中看到它,這裡有一個
Copy
按鈕,點選它,并且妥善儲存好這個内容。
這裡特别注意,這個
Copy
隻有一次機會,點選後就沒得點了,是以這個操作前往别犯糊塗。
推送到Nuget.org
這裡有個特别要注意的技巧,通過釋出多個包的時候,會存在依賴關系,我們應該将被依賴的包先釋出,再逐漸釋出後面的包。
推送到Nuget.org特别簡單,一句指令即可:
nuget push .\xxxxxxx.xxxxxxx.xxxxxxx.x.x.x.nupkg $ApiKey -Source https://api.nuget.org/v3/index.json
将其中
xxxxxxx.xxxxxxx.xxxxxxx.x.x.x.nupkg
替換成自己包的名稱即可,将
$ApiKey
替換成前面保管好的密鑰。
這裡如果你是要推送到自己的私有倉庫,隻需要把ApiKey和Source改成自己私有倉庫對應的即可。
看到
Your package was pushed.
即表示釋出成功。
這時候前往Nuget官網或者在Visual Studio進入Nuget包管理就可以搜到它了(新包大概需要5-6分鐘建立索引)。
離線安裝Nuget包
有時候,如果你在本地打包好了,但是不想釋出到包平台,其實也可以本地離線安裝,這個操作起來非常友善。
建立本地包源
打開Visual Studio頂部菜單中的
工具
-
Nuget包管理器
-
程式包管理器設定
進入Nuget包設定頁面。
切換到左側
Nuget包管理器
-
程式包源
,在右上角找到
+
按鈕添加一個新的包源。
修改掉建立後的預設值,比如名稱可以改成
Local Package Source
,然後點選
源
那一行的
...
按鈕選擇放置了本地Nuget包的檔案夾,最後點選
更新
按鈕。
使用本地包源
接下來,前往你要添加Nuget包的項目上右鍵,進入
管理Nuget程式包
菜單,進入
浏覽
界面,關鍵的一步是,切換最右側的包源為剛才添加的本地那個。
這時候你就可以看到你本地的包了,你可以像平時一樣安裝即可。
不過需要注意的是,如果你安裝的包如果對其他包存在依賴,那麼你可能需要先安裝依賴包,也許這個依賴包是公開包源的,需要先切回如
Nuget.org
等線上包源。
參考
- https://github.com/TaylorShi/HelloNugetPackage
- NuGet簡介
- 安裝NuGet用戶端工具
- 快速入門:使用 Visual Studio 建立和釋出包(.NET Framework、Windows)
- 使用dotnet CLI建立NuGet包
- 辨別項目格式
- .NET Framework生成NuGet包
- C# NuGet打包和離線安裝
- Visual Studio NuGet離線安裝
- 共享你的控件 -- 用NuGet包裝自己的控件
- .NET Framework生成NuGet包
- https://www.nuget.org
- .NET SDK項目的MSBuild引用
- .nuspec引用
- 快速入門:建立和釋出包 (dotnet CLI)