2013-10-18 20 views
6

Yerel makinedeki GAC (Genel Montaj Önbelleği) bir derleme kaydedilmişse, programsal olarak kontrol etmenin en kolay yolu nedir? Yerel makinede GAC olup olmadığını kontrol etmek için bir montaj DLL veya bir Assembly nesnesinin kendisine bir yer verebileceğim .NET API kullanımı kolay mı? Benim durumumda kontrol ettiğim derleme zaten program kontrolünün geçerli AppDomain'inde yüklenecektir, bu yüzden ben Assembly.ReflectionOnlyLoad numaralı telefonu arayarak emin değilim ve bir istisna yakalamak diğer yayınlarda önerildiği gibi çalışacaktır, artı gibi görünüyor hacky..NET derlemesinin GAC'de yüklü olup olmadığı nasıl belirlenir?

İdeal olarak, denetlemek için gacutil.exe gibi harici bir yürütülebilir dosyayı çağırmaktan kaçınmak istiyorum.

+0

olası yinelenen http://stackoverflow.com/ sorular/1933947/kontrol için-gac-montajı) – JMK

+0

Fusion api, [IAssemblyCache.QueryAssemblyInfo] kullanın (http://stackoverflow.com/a/2611435/17034). –

+0

@Hans Belki de tamamen yönetilen bir çözüm istediğimi belirtmeliydim ama siz haklısınız, Fusion API da istediğimi yapacaktı. Tamamen yönetilen bir çözüm için yaptığım şey için cevabımı görün. –

cevap

11

Bu soru aşağıdaki sorulara çok benzer ama benim biraz daha hassas, artı ne kabul edilen bir yanıt vardı ve sunulan cevapların hiçbiri tam veya optimum gibiydi:

Asıl olarak aşağıdakilerin en iyi yaklaşım olduğunu düşündüm ancak montajın tam adını belirtmedikçe ve try/catch öğesinin hacky beacause'ı olmadıkça çalışmaz, ancak basittir ve birçok durumda işe yarar:

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; 
    } 
} 

Bu Fusion API kullanarak bir try/catch olmadan çalışır daha iyi bir yaklaşımdır. Bir deste daha kod ama kısmi montaj adları ile çalışır: CodeBase null ise

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. Benim deneyimime assemblyFullName FULL olmak zorunda. Bu, processorArchitecture = MSIL veya benzerlerini içerir. Yani testimde bu testte AssemblyName.FullName + ", processorArchitecture = MSIL" kullanıyorum. Ayrıca "hayır" demeden önce diğer 2 alternatifi de deneyin. ("AMD64" ve "x86") Bu olmadan aldığım tek eşleşme, çok az sayıda olan "c: \ Windows \ assembly \ GAC" içinde derlemelerdi. – Wolf5

0

Kontrol

if (asm.CodeBase == null) { 
    // IN GAC 
} 
([bir montaj için GAC Kontrol] arasında
İlgili konular