MS_NuGetPackageManagement - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

NuGet を䜿甚したパッケヌゞ管理

NuGet の操䜜

GUI での操䜜

Microsoft Learn を参照。

CUI での操䜜

Microsoft Learn を参照。

移行メモ衚蚘: 原文の「doscs、learnを参照。」は
**docs珟 Microsoft Learn**の入力誀りず刀断し、
統合しお「Microsoft Learn を参照。」に修正した。

補足珟圚の操䜜手段最新化: 本ペヌゞの蚘述は
packages.config + nuget.exe + パッケヌゞ マネヌゞャヌ コン゜ヌル
を前提ずしおいる。珟圚は次の 3 系統がある。

手段 察象 備考
dotnet CLI SDK スタむル プロゞェクト 珟圚の第䞀候補dotnetコマンド
パッケヌゞ マネヌゞャヌ UI 䞡方 Visual Studio の GUI
パッケヌゞ マネヌゞャヌ コン゜ヌルPowerShell 䞻に packages.config Install-Package 等
nuget.exe packages.config ç³» レガシヌ
dotnet add package Newtonsoft.Json --version 13.0.3
dotnet remove package Newtonsoft.Json
dotnet list package --outdated          # 曎新可胜なものを列挙
dotnet list package --vulnerable        # 脆匱性のあるものを列挙
dotnet restore

dotnet list package --vulnerable は、
䟝存パッケヌゞの既知の脆匱性を怜出する。
CI に組み蟌んでおくず、サプラむ チェヌン䞊のリスクを継続的に怜知できる。

アセンブリ参照先の皮類

GAC (Global Assembly Cache)

GAC に登録されるような埓来のMicrosoft Windows Installerで
配垃されるようなパッケヌゞは、今たでどおり GAC に登録されおいるものを参照する。

NuGet

GAC に登録されおいないパッケヌゞ (OSS ラむブラリなど) は、
もちろん個別にパッケヌゞをダりンロヌドし、それを参照するこずもできる。
しかし、そのパッケヌゞが NuGet に登録されおいれば、
NuGet のメリットを享受するために NuGet 経由でむンストヌルするのが良いのではないかず思われる。

それ以倖

GAC にも NuGet にも登録されおいないパッケヌゞを䜿甚する堎合は、
個別にダりンロヌドし、プロゞェクトから参照させる。

泚意事項

ロヌカルコピヌ

NuGet でむンストヌルしたパッケヌゞ (*.dll) は、GAC には含たれない。
このため、NuGet でむンストヌルしたパッケヌゞをアプリケヌションで䜿甚する堎合、
「ロヌカルコピヌ」は必ず「True」にしおおくこず。

補足.NET Core 以降では GAC が無い最新化: 本節の 3 分類は
.NET Framework 前提である。

.NET Framework .NET Core / .NET
GAC あり共有配眮 廃止
参照の解決 GAC → bin の順 deps.json に埓う
ロヌカルコピヌ 明瀺的に True にする必芁 既定でアプリ配䞋に出力
フレヌムワヌク マシンに 1 ぀の系列 アプリごずSCD なら同梱

GAC 廃止の意味は倧きく、
「マシン党䜓で 1 ぀の版を共有する」ずいう前提そのものが無くなった。
これにより、

  • アプリごずに異なる版のラむブラリを䜿えるDLL Hell の解消
  • 管理者暩限なしで配眮できる
  • アンむンストヌル挏れによる残骞が生じない

ずいう利点が埗られた
詳现は .NETアセンブリ / アセンブリ。

ただし .NET Core でも、
ビルド出力に NuGet 参照がコピヌされないずいう別の珟象がある
埌述の.NET Core の堎合を参照。

もし、こんなこずをしおしたった堎合はどうなる

補足この節は packages.config 固有: 以䞋は、
packages.config 方匏で「参照蚭定 / packages.config / packages フォルダ」
の 3 ぀が二重管理になっおいる
こずから生じる問題矀である。

【packages.config 方匏】3 箇所を敎合させる必芁がある

   .csproj の <Reference><HintPath>   ← 参照蚭定
   packages.config                    ← 入れたパッケヌゞの䞀芧
   packages\ フォルダ                 ← 実䜓

【PackageReference 方匏】1 箇所だけ

   .csproj の <PackageReference>      ← これだけ
   実䜓はグロヌバル パッケヌゞ フォルダ %USERPROFILE%\.nuget\packages

PackageReference に移行すれば、本節の問題はほがすべお消える。
既存プロゞェクトの移行方法は埌述の Package Reference を参照。

手動で、NuGet でむンストヌルしたパッケヌゞの参照蚭定を解陀した

ビルド

  • 参照蚭定を解陀したパッケヌゞを䜿甚しおいない堎合は、通る。
  • (ただし、参照蚭定、packages.config、packages フォルダの敎合性は厩れたたた)

Install-Package

  • 既にむンストヌルされおいたす。ずいうメッセヌゞが衚瀺され、倉わりなし。
  • (ただし、参照蚭定、packages.config、packages フォルダの敎合性は厩れたたた)

Update-Package

  • 圓該パッケヌゞに曎新がなかった堎合

    • 曎新はありたせん。ずいうメッセヌゞが衚瀺され、倉わりなし。
    • (参照蚭定、packages.config、packages フォルダの敎合性は厩れたたた)
  • 圓該パッケヌゞに曎新があった堎合

    • 問題なく曎新が行われる。
    • 参照蚭定、packages.config、packages フォルダの敎合性も盎る。

Uninstall-Package

  • packages.config からは削陀されるが、
    packages フォルダから削陀する際に、正垞に削陀できなかった旚の譊告が出る。
  • Visual Studio を再起動し、プロゞェクトを再床開くず、
    そのずき packages フォルダからパッケヌゞが削陀される。
  • 参照蚭定、packages.config、packages フォルダの敎合性も盎る。

packages フォルダから、手動でフォルダを消した

消したパッケヌゞが自動的に埩元され、ビルドは正垞終了する。

パッケヌゞの埩元は、Visual Studio や、MSBuild でビルドした際、
足りないパッケヌゞを自動的に NuGet サむトからダりンロヌドする機胜である。

パッケヌゞの埩元を行うための蚭定

  • Visual Studio の [ツヌル]-[オプション] でオプション画面を開く。
  • ツリヌの䞭から、[NuGet パッケヌゞ マネヌゞャヌ]-[党般] を遞択する。
  • 「足りないパッケヌゞをダりンロヌドするこずを NuGet に蚱可」にチェックを入れる。

さらに、MSBuild などのコマンドラむンツヌルでのビルド時に、
足りないパッケヌゞをダりンロヌドするには、以䞋の蚭定を行う。

  • Visual Studio の [゜リュヌション ゚クスプロヌラヌ] を右クリックし、
    「Enable NuGet Package Restore」を遞択する。

これにより、゜リュヌションフォルダ盎䞋に**「.nuget」**フォルダができ、
コマンドラむンツヌルでのビルド時でも、足りないパッケヌゞがあれば、
ダりンロヌドしおくれる(MSBuild だけでなく、devenv によるビルドでも有効)。

※ この動䜜は、Visual Studio 2015 (NuGet 2.7) で倉曎されおいる。

packages フォルダそのものを削陀した

䞊蚘ず同様、パッケヌゞが埩元され、ビルドは正垞終了する。

補足.nuget フォルダ方匏は廃止枈み: 䞊蚘の
「Enable NuGet Package Restore」による .nuget フォルダ方匏
MSBuild 統合による埩元は、NuGet 2.7 で非掚奚
になった
埌述の Visual Studio 2015。

珟圚は **「自動埩元」**が既定で、
ビルドの前に NuGet 自身が埩元を行うため、
.nuget\NuGet.targets をプロゞェクトに取り蟌む必芁はない。

# CI などで明瀺的に埩元する堎合
dotnet restore          # SDK スタむル
nuget restore Foo.sln   # packages.config ç³»
msbuild -t:restore      # MSBuild 統合

叀いリポゞトリを開いたずきに .nuget フォルダが残っおいたら、
マむグレヌションが枈んでいないサむンである。

packages.config を手動で線集した

<package> タグを消した

  • Install-Package
    成功 (ふたたび packages.config に <package> が生成される)
  • Update-Package
    倱敗 (パッケヌゞがむンストヌルされおいないずのメッセヌゞが衚瀺される)
  • Uninstall-Package
    譊告 (packages フォルダから削陀する際に、正垞に削陀できなかった旚の譊告が出る。
    Visual Studio を再起動し、プロゞェクトを再床開くず、
    そのずき packages フォルダからパッケヌゞが削陀される)

バヌゞョン番号を線集した

  • 存圚するバヌゞョン番号の堎合
    ビルドは成功し、線集したバヌゞョン番号のパッケヌゞが packages フォルダに栌玍される。
    このずき、線集前のバヌゞョンのパッケヌゞは packages フォルダからは削陀されない。
    このため、以䞋の䞍敎合が起きる。

    • packages フォルダに、バヌゞョンの異なる 2 ぀のパッケヌゞが混圚する。
    • 参照蚭定も解陀されないので、プロゞェクトは線集前のバヌゞョンのパッケヌゞを参照し続ける。
    • このため、packages.config に曞かれたバヌゞョン番号ず、
      実際に参照しおいるバヌゞョン番号が䞀臎しないこずになる。
  • 存圚しないバヌゞョン番号の堎合
    「NuGet パッケヌゞの埩元がプロゞェクト {プロゞェクト名} に察しお倱敗したした」
    ずいうメッセヌゞは衚瀺されるが、

    • ビルド自䜓は成功する(線集前のバヌゞョン番号のパッケヌゞの削陀が行われないため。)。
    • この堎合も、以䞋の䞍敎合が起きる。
      • packages フォルダには、線集前のバヌゞョン番号のパッケヌゞのみが残る。
      • 参照蚭定も解陀されないので、プロゞェクトは線集前のバヌゞョンのパッケヌゞを参照し続ける。
      • このため、packages.config に曞かれたバヌゞョン番号ず、
        実際に参照しおいるバヌゞョン番号が䞀臎しないこずになる。

補足この䞀連の怜蚌の結論: 原文が䞹念に怜蚌しおいる通り、
packages.config を手で線集しおも、参照蚭定.csprojは远埓しない。
結果、**「宣蚀ず実䜓がずれたたたビルドが通る」**ずいう
最も厄介な状態が生たれる。

芋分け方:

# .csproj の HintPath ず packages.config のバヌゞョンを突き合わせる
grep -o 'packages\\[^\\]*\\' *.csproj | sort -u
grep -o 'version="[^"]*"' packages.config | sort -u

確実に盎す手順は、原文の怜蚌結果に沿えば
Uninstall-Package → Install-Packageたたは Update-Packageである
どちらも 3 者の敎合性を回埩させる。

根本的な察凊は PackageReference ぞの移行で、
こちらは .csproj の 1 箇所しか無いため、ずれようがない。

同様に参照蚭定ずの敎合性が厩れる。

  • プロゞェクトファむル.csproj、.vbproj内の<HintPath></HintPath>のタグを修正する。
  • 若しくは、Uninstall-Package -> Install-Package を行う。

その他のトピック

package バヌゞョンの倉曎時の泚意事項

泚意事項

NuGet は、Install-Package を行った際に、バヌゞョン間の問題を解決するために、
"assemblyBinding -> dependentAssembly -> bindingRedirect" を远加する。

このため、

  • Update-Package
  • Uninstall-Package -> Install-Package

によっお package のバヌゞョンを倉曎した堎合、問題を起こすこずがある。

この堎合、䞀床、assemblyBinding section を削陀した埌に、
Add-BindingRedirect を実行しお、bindingRedirect を再生成する。

補足bindingRedirect ずは䜕か: .NET Framework は
参照したアセンブリの版が完党䞀臎するこずを芁求する
アセンブリ の厳密名による匷いバむンド。
このため、

あなたのアプリ ──> LibA 1.0 ──> Newtonsoft.Json 9.0
             └───> LibB 2.0 ──> Newtonsoft.Json 13.0

  → LibA は 9.0 を芁求するが、実際に眮かれおいるのは 13.0
  → 「ファむルたたはアセンブリを読み蟌めたせんでした」で萜ちる

ずいう DLL Hell が起きる。
これを「9.0 の芁求は 13.0 で満たす」ず読み替えさせるのが
bindingRedirectapp.config / web.configである。

<dependentAssembly>
  <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
  <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>

NuGet がこれを自動生成するため、
パッケヌゞのバヌゞョンを䞊げ䞋げするず叀い蚘述が残っお矛盟する——
ずいうのが原文の指摘する問題である。
察凊section を消しお Add-BindingRedirect で䜜り盎すは珟圚も有効。

.NET Core 以降では、この問題自䜓が存圚しない。
バむンドの解決が deps.json に基づき、
**「参照より新しい版があればそれを䜿う」**ずいう緩やかな芏則になったため、
bindingRedirect は䞍芁になった。
.NET Framework から移行する動機の䞀぀がここにある。

参考

NuGetパッケヌゞの DL 先の倉曎方法

倉曎方法

  • nuget.config を甚意し、芪ディレクトリに配眮、
    ここに、repositoryPath を指定するこずで NuGet パッケヌゞの DL 先を倉曎できそう。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value=".\sharedpackages" />
  </config>
</configuration>
  • なお、怜蚌の結果、゜リュヌション分割によっお、
    NuGet パッケヌゞの DL 先packagesが分割される暡様。
    既定では *.sln ファむルず同じ階局に packages フォルダができる

  • 埓っお、このケヌスで packages を共有したい堎合、

    • ぀の゜リュヌションのルヌト・ディレクトリに nuget.config を配眮するか、
    • ぀の゜リュヌションの其々の䞊䜍ディレクトリに nuget.config を配眮し、
      同じ repositoryPath を指すか、

で、察応ができる。

  • 以䞋は、぀の *.sln ファむルClassLibrary.sln、ConsoleApp1.sln間で
    packages を共有した䟋。
フォルダ/ファむル名                                                                    皮類          
-----------------------------------------------------------------------------------------------------
Root1                                                                                  <Dir>         
 ├ ClassLibrary                                                                       <Dir>         
   ├ ClassLibrary1                                                                  <Dir>         
     ├ Properties                                                                 <Dir>         
       └ AssemblyInfo.cs                                                             <File>   
     ├ Class1.cs                                                                       <File>   
     ├ ClassLibrary1.csproj                                                            <File>   
     └ packages.config                                                                 <File>   
   ├ ClassLibrary2                                                                  <Dir>         
     ├ Properties                                                                 <Dir>         
       └ AssemblyInfo.cs                                                             <File>   
     ├ Class1.cs                                                                       <File>   
     ├ ClassLibrary2.csproj                                                            <File>   
     └ packages.config                                                                 <File>   
   └ ClassLibrary.sln                                                                    <File>   
 ├ ConsoleApp1                                                                        <Dir>         
   ├ ConsoleApp1                                                                    <Dir>         
     ├ Properties                                                                 <Dir>         
       └ AssemblyInfo.cs                                                             <File>   
     ├ App.config                                                                      <File>   
     ├ ConsoleApp1.csproj                                                              <File>   
     ├ packages.config                                                                 <File>   
     └ Program.cs                                                                      <File>   
   └ ConsoleApp1.sln                                                                     <File>   
 ├ sharedpackages                                                                     <Dir>         
   └ Newtonsoft.Json.10.0.3                                                         <Dir>         
       ├ lib                                                                        <Dir>         
       ├ tools                                                                      <Dir>         
       ├ LICENSE.md                                                                      <File>   
       └ Newtonsoft.Json.10.0.3.nupkg                                                    <File>   
 └ nuget.config                                                                            <File>   

補足PackageReference では䞍芁になる: この
「゜リュヌションごずに packages が分裂しお重耇ダりンロヌドされる」
ずいう問題も、PackageReference 方匏では発生しない。

packages.config PackageReference
実䜓の眮き堎所 .sln ごずの packages\ ナヌザヌ単䜍のグロヌバル フォルダ
既定のパス <sln>\packages %USERPROFILE%\.nuget\packages
重耇 ゜リュヌション数だけ増える 1 ぀を共有
蚭定キヌ repositoryPath globalPackagesFolder
<!-- PackageReference 方匏でグロヌバル フォルダを倉える堎合 -->
<configuration>
  <config>
    <add key="globalPackagesFolder" value="D:\nuget-cache" />
  </config>
</configuration>

repositoryPath は PackageReference では効かないため、
移行埌も叀い蚭定が残っおいるず混乱のもずになる。

なお、CI で毎回ダりンロヌドしたくない堎合は、
NUGET_PACKAGES 環境倉数でキャッシュ堎所を指定し、
ビルド ゚ヌゞェント間で共有するのが定石である。

参考

マむグレヌション

Visual Studio 2015

NuGet 自䜓のバヌゞョンをNuGet 2.7 以降に䞊げるず、リストア方法も倉曎になる。

この堎合、以䞋のように、リストア方法をマむグレヌションする必芁がある。

参考

Visual Studio 2017

Package Reference

Visual Studio 2017 からは、packages.config ではなく、
Project ファむルに統合された Package Reference を䜿甚できる。

ただし、䞀郚問題を芳枬しおいる。

補足移行手順最新化: 珟圚は
packages.config → PackageReference の移行が掚奚されおおり、
Visual Studio に移行機胜が甚意されおいる。

゜リュヌション ゚クスプロヌラヌで packages.config を右クリック
  → [packages.config を PackageReference に移行する]

移行によっお埗られるもの:

効果 内容
3 者の二重管理が消える .csproj 1 箇所になる
掚移的䟝存が明瀺されなくなる 盎接䜿うものだけ曞けばよい
ディスク䜿甚量の削枛 グロヌバル フォルダを共有
bin の肥倧化が枛る 必芁なものだけ出力
dotnet CLI が䜿える CI がシンプルになる

泚意点:

  • install.ps1 / uninstall.ps1 を持぀パッケヌゞは動かない
    PackageReference は PowerShell スクリプトを実行しない
  • content フォルダで蚭定ファむルを配るパッケヌゞも同様
    contentFiles ぞの察応が必芁
  • 掚移的䟝存が自動で解決されるため、
    これたで明瀺されおいた䟝存が .csproj から消える
    原文が .NET Core の堎合 で觊れる NU1701 等の
    挙動差にも぀ながる

原文が指す「䞀郚問題」CS0246も、
この掚移的䟝存の扱いの違いに起因するものである。

.NET Core の堎合

  • .NET Core で、ビルド出力に NuGet リファレンスがコピヌされない。

    • 以䞋を csproj ファむルに远加するず NuGet リファレンスをビルド出力にコピヌする。
<PropertyGroup>
  <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

補足CopyLocalLockFileAssemblies が芁る理由: .NET Core では、
dotnet build の出力bin\に䟝存 DLL が入らないこずがある。
これは「実行時に deps.json を芋おグロヌバル フォルダから解決する」
ずいう蚭蚈のためで、䞍具合ではない。

【dotnet run / dotnet publish】
   deps.json 経由で解決される → 問題なし

【bin\ をそのたたコピヌしお別の堎所で動かす】
   グロヌバル フォルダが無い → 芋぀からない

このため、

状況 察凊
通垞の配眮 dotnet publish を䜿うすべお揃う
クラス ラむブラリを他所に枡す CopyLocalLockFileAssemblies
プラグむン DLL を䜜る CopyLocalLockFileAssemblies + EnableDynamicLoading

**原則は「dotnet publish を䜿う」**であり、
CopyLocalLockFileAssemblies は
ビルド出力を盎接配る必芁がある堎合の回避策ず䜍眮づけられる
.NET Coreのデプロむ。

NU1701 は、
「.NET Framework 甚のパッケヌゞを .NET Core 系から参照した」
ずいう譊告である。動くこずもあるが保蚌されないため、

  1. netstandard2.0 察応版があるか探す第䞀候補
  2. 無ければ代替ラむブラリを探す
  3. どうしおも必芁なら NoWarn で抑止し、動䜜確認を厚くする

ずいう順で怜蚎する。

参考サむト

nuget.org

珟圚登録されおいる NuGet パッケヌゞを怜玢可胜

NuGet の機胜や䜿い方などのドキュメントを閲芧可胜

Microsoft Learn

ツヌル

PowerShell

移行


Tags: 移行, .NET開発, デプロむ, NuGet

⚠ **GitHub.com Fallback** ⚠