📦

C#/.NET - nuget.org につながらない環境でもビルドできるようにする方法

2024/10/07に公開

はじめに

nuget.org で配付されているような NuGet パッケージを参照している、C# 等の .NET プロジェクトについての話です。

そう滅多にある話ではないのですが、希に、インターネットへの接続ができない現場、つまり nuget.org に接続ができない状況で、前述のような .NET プロジェクトのビルドの必要が発生することが、自分にはありました。そのような状況下で、NuGet パッケージを参照している .NET プロジェクトをビルドできるようにする方法を、今回は紹介します。

なお以下の内容は、OS は Windows での動作を確認してます。macOS や Linux 各種ディストリビューションなど、他の OS 環境については確認はしていません (が、たぶん、いくつかのファイルフォルダパスの違いを除けば、OS に依らずそのまま当てはまると思います)。

キャッシュできていればビルドはできる

実は、いちどでも NuGet パッケージ参照の復元やビルドに成功しているプロジェクトであれば、nuget.org に接続できない状況であっても、とくに何もせずとも、パッケージ復元およびビルドは可能です。プロジェクトファイルを Visual Studio で開いての Ctrl + Shift + B を押してのビルド、あるいは dotnet build をはじめ、dotnet restoredotnet run のような dotnet CLI のコマンド実行も、いずれもインターネット接続がなくても成功します。ただし、以下のような「脆弱性情報を取得できない」という警告は発生します。

warning NU1900:
Error occurred while getting package vulnerability data:
Unable to load the service index for source https://api.nuget.org/v3/index.json.

なぜ nuget.org に到達できないのにビルドが成功するかといと、パッケージ復元に成功した NuGet パッケージは通常、デバイスのホームディレクトリ配下のフォルダにキャッシュとして保存されているためです。そのキャッシュフォルダに目的の ID とバージョンの NuGet パッケージが見つかる限りは、そのキャッシュからパッケージ復元に成功する仕組みです。

ちなみに NuGet パッケージのキャッシュ保存先は、Windows だと、%USERPROFILE%\.nuget\packages フォルダ以下になります。

パッケージ追加やバージョン変更はプロジェクトファイルを直接変更

このように、パッケージ復元やビルドは、対象の .NET プロジェクトが参照している ID とバージョンの NuGet パッケージがキャッシュに見つかる限りは成功します。しかし、.NET プロジェクトへの別の NuGet パッケージの参照追加や、あるいは既に参照済みの NuGet パッケージのバージョンを更新する場合、Visual Studio の NuGet パッケージマネージャーや dotnet CLI による dotnet add package コマンドは機能しません。

インターネット接続がない環境で Visual Studio の NuGet パッケージマネージャーを開くと、エラーとなってしまっている様子のスクリーンショット

これらの作業はさすがに、nuget.org への接続が必要となるからです。

とはいえ、手段がないわけではなくて、.NET プロジェクトファイル (C# なら .csproj ファイル) をエディタで直接編集して、<PackageReference> ノードを追加したり変更したりすれば可能です。

*.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <!-- 👇こういう、NuGet パッケージ参照の指定を手書きすればよい -->
    <PackageReference Include="Selenium.WebDriver" Version="4.25.0" />
    <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="129.0.6668.8900" />
  </ItemGroup>

</Project>

.NET プロジェクトファイル (C# なら .csproj ファイル) をエディタで直接編集して、NuGet パッケージ参照を追加・変更した場合であってもとにかく、該当する ID・バージョンの NuGet パッケージがキャッシュ済みであれば、パッケージ復元とビルドは成功します。

ローカルディスクに NuGet パッケージファイルを保存しておき、パッケージソースとして登録

以上で、多くのシナリオをカバーできるのではないかと思います。とはいえ、「やっぱり Visual Studio の GUI のパッケージマネージャーで操作したい」であるとか、「NuGet パッケージファイル (.nupkg) は手元にあるんだけど、キャッシュはされていない」といった状況があるかもしれません。

そのような場合は、ローカルディスク上に適当なフォルダを作成しておき、そのフォルダに NuGet パッケージファイル (.nupkg) を放り込んでおけば大丈夫です。

ローカルディスク上のフォルダに NuGet パッケージファイル (.nupkg) を保存している様子のスクリーンショット

その上で、NuGet パッケージの設定にて、このローカルディスク上のフォルダを「パッケージソース」として追加すればよいのです。

ローカルディスク上のフォルダを「パッケージソース」として追加するには、dotnet CLI を使う場合は dotnet nuget add source コマンドを実行します。例えば、C:\Packages\Local フォルダに NuGet パッケージファイルを溜めてあり、これをパッケージソースとして使いたい場合は、以下のように実行します。

dotnet nuget add source C:\Packages\Local -n Local

コマンドライン引数の -n は続けてパッケージソースの "名前" を指定するものです。上記例では「Local」というパッケージソース名にしてあります。

以上の状態で、例えば Visual Studio の GUI による NuGet パッケージマネージャーを開き、右上のパッケージソースのドロップダウンリストを開くと、いま追加したパッケージソースの名前が選べるようになっていますから、これを選択することで、ローカルディスク上のフォルダに置いておいた NuGet パッケージ (.nupkg ファイル) を GUI で参照、追加したりバージョンを変更したりすることができるようになります。

Visual Studio で、ローカルディスク上のフォルダを指すパッケージソースを選択した様子のスクリーンショット

もちろん、dotnet add package コマンドによる NuGet パッケージ参照の追加やバージョン変更も正しく機能します。

NuGet パッケージファイル (.nupkg) の入手

nuget.org からダウンロード

NuGet パッケージをパッケージファイル (.nupkg) として nuget.org からダウンロードしておくには、Web ブラウザで nuget.org にアクセスし、目的のパッケージの目的のバージョンのページを開いた状態で、ページ右側にある「Download package」のリンクをクリックすると、当該 NuGet パッケージのパッケージファイル (.nupkg) がダウンロードできます。

nuget.org 上にて、とある NuGet パッケージの「Download package」リンクが示されている様子

キャッシュから持ってくることもできる

ちなみに、本記事冒頭で紹介した、NuGet パッケージのキャッシュフォルダには、実は NuGet パッケージファイルそのもの (.nupkg) も保存されています。

NuGet パッケージのキャッシュフォルダに保存されている、.nupkg ファイルを示している様子

なので、この NuGet パッケージのキャッシュフォルダから、パッケージファイル(.nupkg) を回収して保全しておくことも可能です。

まとめ

以上、インターネット接続がない環境であっても、NuGet パッケージを参照している .NET プロジェクトについて、パッケージ復元とビルドが行えるようにする方法についての説明でした。上記記載中は nuget.org についてしか明確には言及していませんが、GitHub Packages をはじめ、いずれのパッケージフィードから配付される NuGet パッケージであっても要領は同じはずです。

なお、当然のことながら、NuGet パッケージの再配布条件や使用許諾は、パッケージごとに異なりますので、実際の運用にあたってはその点の取り扱いはくれぐれもご注意ください。

Discussion