メインコンテンツまでスキップ

グローバルアセンブリキャッシュ(GAC)

グローバルアセンブリキャッシュ(GAC)は、コンピューター上の複数のアプリケーションによって共有されるアセンブリを格納するための場所です。具体的には、以下のフォルダーに格納されます。

  • .NET Framework 3.5以前: C:\Windows\assembly
  • .NET Framework 4以降: C:\Windows\Microsoft.NET\assembly

GACには厳密名を持つアセンブリのみを登録することができます。厳密名は、アセンブリ名、バージョン番号、パブリックキーの3つの要素から構成されます。これにより、同じアセンブリ名を持つ異なるバージョンのアセンブリを共存させることが可能になります。また、複数のベンダーが同じアセンブリ名を使用する場合でも、厳密名によって衝突を回避することができます。

.NET Frameworkアプリケーションがアセンブリを検索する際の動作は公式ドキュメントに詳しく記載されていますが、端的に言えばまずGACの場所が検索され、次にアプリケーションフォルダーが検索されます。検索パスから見つからない場合はFileNotFoundException例外がスローされます。GACに登録しておくことで、アプリケーションフォルダーにアセンブリのコピーを配置することなく参照することができるようになります。また、ネイティブアプリケーションからCOM相互運用を経由してアセンブリがロードされる場合もGACが考慮されるため、アセンブリをCOMコンポーネントとして公開する場合は同時にGACに登録しておくことも一般的です。

GACのインストール方法

アセンブリをGACに配置する方法は以下の3つがあります。

  1. Windowsインストーラーを作成してMSIファイルからインストールする。
  2. Windows SDKに含まれるgacutil.exeを使用する。
  3. PowerShellからSystem.EnterpriseServices.Internal.Publish.GacInstallメソッドを呼び出す。

gacutil.exeはWindowsや.NET Frameworkのランタイムには付属しておらず再頒布もできないので、2.の方法は運用環境での使用には適していません。1.の方法はMSIファイルを作成する手間がかかりますが、Microsoftの公式ドキュメントで推奨されている方法になります。3.の方法は手軽に実行できますが、クラスライブラリの動作に起因してエラー処理が難しいという難点があります。また、1.の方法はWindows Installerの参照カウントの仕組みで管理されるのに対して、3.の方法はそれがないため、同じアセンブリが複数の製品で使用される場合は誤ってアンインストールしないよう注意が必要です。

それぞれのインストール方法について説明していきます。

1. Windowsインストーラーを作成する

GACにアセンブリをインストールするMSIファイルを作成する手順は以下のとおりです。

  1. Visual Studioで新しいセットアッププロジェクトを作成します。セットアッププロジェクトは拡張機能になっていますので、こちらを参考にバージョンに応じたものをインストールしてください。

    Setupプロジェクトの選択

  2. ファイルシステムエディターを開きます。

    ファイルシステムエディターを開く

  3. グローバルアセンブリキャッシュのフォルダーを追加します。

    グローバルアセンブリキャッシュのフォルダーを追加する

  4. グローバルアセンブリキャッシュフォルダーを選択し、メニューからプロジェクト出力の追加を選択します。

    グローバルアセンブリキャッシュフォルダーへプロジェクト出力を追加する。

  5. プロジェクトを選択してプライマリ出力を選択し、[OK]ボタンをクリックします。

    プライマリ出力の追加

  6. プロジェクトをビルドします。

参考情報

2. gacutil.exeを使用する

Visual StudioやWindows SDKに付属する.NET Framework SDKには、GACを操作するための開発者向けツールgacutil.exeが付属しています。gacutil.exeの再頒布は許諾されていないため運用環境へのインストール方法としては適していませんが、開発環境ではこのツールを使用するのが便利です。gacutil.exeを使用してGACにアセンブリをインストールする手順は以下のとおりです。

  1. 管理者としてコマンドプロンプトを起動します。

  2. .NET Framework SDKがインストールされているフォルダーに移動します。

    cd C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools
  3. gacutil /i <アセンブリのフルパス>コマンドを実行します。

    C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools>gacutil /i "C:\source\repos\ClassLibrary1\bin\Debug\ClassLibrary1.dll"   
    アセンブリが正しくキャッシュに追加されました

3. PowerShellを使用する

.NET FrameworkにはGACにアセンブリをインストールするためのクラスライブラリSystem.EnterpriseServices.Internal.Publishが含まれています。このクラスをPowerShellから呼び出すことで、GACにアセンブリをインストールすることができます。手順は以下のとおりです。

  1. 管理者としてPowerShellを起動します。

  2. 以下のコマンドレットを実行します。

    [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
    $publish = New-Object System.EnterpriseServices.Internal.Publish
    $publish.GacInstall("<アセンブリのフルパス>")

ちなみに、GacInstallメソッドはアセンブリのインストールに失敗してもエラーを返すことも例外をスローすることもありません。Applicationのイベントログには"COM+ SOAP Services"のソースでエラーが記録されるようなので、こちらからエラーが発生していないか確認すると共に、実際にインストールが成功しているかどうかテストを実施するようにしましょう。

GacInstall失敗のイベントログ

"COM+ SOAP Services"のソースで記録されるのは、恐らくこのクラスライブラリが.NET FrameworkのアセンブリをCOM+コンポーネントとしてインストールする際に使用されるためと思われます。

GACの確認方法

GACに登録されているアセンブリを確認する方法はいくつかあります。

  1. Windows Explorerを使用する。
  2. gacutil.exeを使用する。
  3. PowerShellを使用する。

1. Windows Explorerを使用する

GACにインストールされたアセンブリは以下のフォルダーに格納されるため、エクスプローラーから確認することができます。

  • .NET Framework 3.5以前: C:\Windows\assembly
  • .NET Framework 4以降: C:\Windows\Microsoft.NET\assembly

エクスプローラーからGACを確認する

ちなみに、Windows 7およびWindows Server 2008 R2以前のバージョンでは、.NET Framework 3.5以前のバージョン限定となりますがアセンブリキャッシュビューアーという機能がエクスプローラーのシェル拡張として既定でインストールされており、下図のようにアセンブリの一覧表示や追加、削除が可能でした。

アセンブリキャッシュビューアー

しかし、アセンブリキャッシュビューアーはWindows 8およびWindows Server 2012以降は利用されなくなりました。シェル拡張は現在も.NET Framework 3.5の一部としてC:\Windows\Microsoft.NET\Framework\v2.0.50727\shfusion.dllに含まれており、レジストリにも\HKEY_CLASSES_ROOT\CLSID\{1D2680C9-0E2A-469d-B787-065558BC7D43}配下に登録されています。.NET Framework 3.5以前のGACしか参照できないので実用性はほとんどありませんが、任意の場所にtest.{1D2680C9-0E2A-469d-B787-065558BC7D43}という名前のフォルダーを作成すると、Windows 11でもアセンブリキャッシュビューアーを表示できるようになります。

アセンブリキャッシュビューアーをWindows 11で表示する

2. gacutil.exeを使用する

gacutil.exeを使用して、GACに登録されているアセンブリを確認することができます。一覧を表示する場合はgacutil.exe /l、特定のアセンブリを確認したい場合はgacutil.exe /l <アセンブリ名>を使用します。アセンブリ名は厳密名で指定する必要はありません。

C:\Users\user1>"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\gacutil.exe" /l classlibrary1
グローバル アセンブリ キャッシュには次のアセンブリが含まれています:
classlibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2813d853331ade28, processorArchitecture=MSIL

項目の数 = 1

GACのアンインストール方法

アセンブリをGACからアンインストールする場合、基本的にはインストールした方法と同様の方法を使用します。つまり、Windowsインストーラーを使用してインストールした場合はその製品をアンインストールする、gacutil.exeやSystem.EnterpriseServices.Internal.Publishを使用してインストールした場合はそれらのアンインストールコマンドを使用する、といった流れになります。

なお、WindowsインストーラーでGACにインストールしたアセンブリはgacutil.exeやSystem.EnterpriseServices.Internal.Publishを使用してアンインストールすることはできません。試行した場合はそれぞれエラーになります。

1. gacutil.exeを使用する

gacutil.exeを使用する場合は、gacutil /u <アセンブリ名>コマンドを実行します。アセンブリ名は厳密名で指定する必要はありません。

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools>gacutil /u classlibrary1
アセンブリ: classlibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2813d853331ade28, processorArchitecture=MSIL
アンインストール済み: classlibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2813d853331ade28, processorArchitecture=MSIL
アンインストールされたアセンブリの数 = 1
エラーの数 = 0

ちなみに、Windowsインストーラーでインストールされたアセンブリをgacutil.exeでアンインストールしようとした場合はエラーになります。スキームが<WINDOWS_INSTALLER>になっていますが、他のスキームは見たことがありません。

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools>gacutil /u classlibrary1

アセンブリ: classlibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2813d853331ade28, processorArchitecture=MSIL
アンインストールできません: アセンブリは 1 つまたはそれ以上のアプリケーションで必要とされています
保留中の参照:
スキーム: <WINDOWS_INSTALLER> ID: <MSI> 説明 : <Windows Installer>
アンインストールされたアセンブリの数 = 0
エラーの数 = 0

2. PowerShellを使用する

System.EnterpriseServices.Internal.Publishを使用する場合は、gacutil.exeを使用する場合と異なりアセンブリのフルパスを指定する必要があります。アセンブリ名や厳密名でアンインストールすることはできないようです。

[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object System.EnterpriseServices.Internal.Publish
$publish.GacRemove("<アセンブリのフルパス>")

GacRemoveに失敗した場合、GacInstallと同様にエラーや例外が返されませんので、Applicationのイベントログから確認する必要があります。

GacRemoveによるアセンブリアンインストールの失敗

なお、こちらもWindowsインストーラーでインストールされたアセンブリをGacRemoveでアンインストールしようとした場合は失敗します。失敗した場合のイベントログは、ファイル名を間違えていた場合などと区別できず単に"グローバル アセンブリ キャッシュからのアセンブリの削除に失敗しました"としか表示されないので、失敗した原因を特定することは難しいです。