2013-10-18 20 views
6

アセンブリがローカルマシンのGAC(グローバルアセンブリキャッシュ)に登録されているかどうかをプログラムで確認する最も簡単な方法は何ですか?いくつかの簡単な.NET APIを使用して、アセンブリDLLまたはAssemblyオブジェクト自体にローカルマシン上のGACに存在するかどうかを確認することができますか?私のケースでは、私がチェックしているアセンブリはすでにプログラムチェックの現在のAppDomainにロードされているので、私はAssembly.ReflectionOnlyLoadを呼び出して例外をキャッチするのか分からないので、他の投稿に示唆したように動作しますハッキー。.NETアセンブリがGACにインストールされているかどうかをプログラムで判断する方法

理想的には、gacutil.exeのような外部実行可能ファイルを呼び出すことを避けたいと思います。

+0

可能重複http://stackoverflow.com/質問/ 1933947/gac-for-an-assembly) – JMK

+0

融合API [IAssemblyCache.QueryAssemblyInfo](http://stackoverflow.com/a/2611435/17034)を使用してください。 –

+0

@Hans私はおそらく完全に管理されたソリューションを望んでいるはずですが、あなたが正しいと思っているはずですが、Fusion APIは私の望むことをやっています。完全に管理されたソリューションのためにやったことについて私の答えを見てください。 –

答えて

11

この質問は、以下の質問に非常に似ていますが、鉱山は、もう少し正確で、プラスどちらも受け入れ答えを持っていたし、提供する回答のどれも完全または最適思えません:

元々、私は以下の方法が最善のアプローチだと思っていましたが、アセンブリの完全な名前を指定しないとうまくいきませんでした。それはtry/catchのハックビーコンです多くの場合のために働く:

public static class GacUtil 
{ 
    public static bool IsAssemblyInGAC(string assemblyFullName) 
    { 
     try 
     { 
      return Assembly.ReflectionOnlyLoad(assemblyFullName) 
          .GlobalAssemblyCache; 
     } 
     catch 
     { 
      return false; 
     } 
    } 

    public static bool IsAssemblyInGAC(Assembly assembly) 
    { 
     return assembly.GlobalAssemblyCache; 
    } 
} 

これはFusion APIを使用してのtry/catchせずに動作するより良いアプローチです。それはたくさんより多くのコードだが、それは部分的なアセンブリ名を使用して動作します:コードベースがnullの場合

public static class GacUtil 
{ 
    [DllImport("fusion.dll")] 
    private static extern IntPtr CreateAssemblyCache(
     out IAssemblyCache ppAsmCache, 
     int reserved); 

    [ComImport] 
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    [Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")] 
    private interface IAssemblyCache 
    { 
     int Dummy1(); 

     [PreserveSig()] 
     IntPtr QueryAssemblyInfo(
      int flags, 
      [MarshalAs(UnmanagedType.LPWStr)] string assemblyName, 
      ref AssemblyInfo assemblyInfo); 

     int Dummy2(); 
     int Dummy3(); 
     int Dummy4(); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    private struct AssemblyInfo 
    { 
     public int cbAssemblyInfo; 
     public int assemblyFlags; 
     public long assemblySizeInKB; 

     [MarshalAs(UnmanagedType.LPWStr)] 
     public string currentAssemblyPath; 

     public int cchBuf; 
    } 

    public static bool IsAssemblyInGAC(string assemblyName) 
    { 
     var assembyInfo = new AssemblyInfo { cchBuf = 512 }; 
     assembyInfo.currentAssemblyPath = new string('\0', assembyInfo.cchBuf); 

     IAssemblyCache assemblyCache; 

     var hr = CreateAssemblyCache(out assemblyCache, 0); 

     if (hr == IntPtr.Zero) 
     { 
      hr = assemblyCache.QueryAssemblyInfo(
       1, 
       assemblyName, 
       ref assembyInfo); 

      if (hr != IntPtr.Zero) 
      { 
       return false; 
      } 

      return true; 
     } 

     Marshal.ThrowExceptionForHR(hr.ToInt32()); 
     return false; 
    } 
} 
+3

Nb。私の経験上、assemblyFullNameはFULLでなければなりません。これには、processorArchitecture = MSILなどが含まれます。私のテストでは、このテストでAssemblyName.FullName + "、processorArchitecture = MSIL"を使用します。また、私が「いいえ」と言う前に、2つの他の選択肢も試してみてください。 ( "AMD64"と "x86") 私はそれがなくても、「c:\ Windows \ assembly \ GAC」内のアセンブリは非常に少数です。 – Wolf5

0

チェック

if (asm.CodeBase == null) { 
    // IN GAC 
} 
([アセンブリ用のGACをチェック]の
関連する問題