2010-07-28 11 views
12

Voy a tener una lista de dll en una carpeta, quiero verificar que exista o no una dll para una aplicación. Si es así, quiero agregar ese nombre de aplicación en la cuadrícula. ¿Puede alguien decir cómo hacerlo mediante programación? Gracias de antemanoProgrammatically Para verificar dll existe en Gac o no. Si es así, mostrarlo en la cuadrícula

+3

Si tiene una lista de archivos DLL en una carpeta, es muy poco probable que esa carpeta forme parte del GAC. –

Respuesta

0

Normalmente, las personas suponen que el GAC se encuentra en c: \\ assembly, que es 99% verdadero. Entonces podría escribir código para iterar a través de los archivos encontrados en esa carpeta.

La forma más ortodoxa sería usar la API de Fusion, que está basada en COM. Un contenedor administrado está disponible en este sitio blog:

http://blogs.msdn.com/junfeng/archive/2004/09/14/229653.aspx

El sitio contiene también código de ejemplo que muestra cómo utilizar la API de fusión para enumerar los conjuntos instalados logró - el código es más o menos escrito para usted, por lo simplemente Ctrl + C y luego Ctrl + V ... :)

http://blogs.msdn.com/b/junfeng/archive/2004/09/14/229650.aspx

HTH ...

9

creo que la forma correcta es la fusión de la API COM.

Aquí cómo usarlo:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace IsAssemblyInGAC 
{ 
    internal class GacApi 
    { 
     [DllImport("fusion.dll")] 
     internal static extern IntPtr CreateAssemblyCache(
      out IAssemblyCache ppAsmCache, int reserved); 
    } 

    // GAC Interfaces - IAssemblyCache. As a sample, non used vtable entries  
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
    Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")] 
    internal interface IAssemblyCache 
    { 
     int Dummy1(); 
     [PreserveSig()] 
     IntPtr QueryAssemblyInfo(
      int flags, 
      [MarshalAs(UnmanagedType.LPWStr)] 
      String assemblyName, 
      ref ASSEMBLY_INFO assemblyInfo); 

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

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

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

     public int cchBuf; 
    } 

    class Program 
    { 
     static void Main() 
     { 
      try 
      { 
       Console.WriteLine(QueryAssemblyInfo("System")); 
      } 
      catch(System.IO.FileNotFoundException e) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 

     // If assemblyName is not fully qualified, a random matching may be 
     public static String QueryAssemblyInfo(String assemblyName) 
     { 
      ASSEMBLY_INFO assembyInfo = new ASSEMBLY_INFO(); 
      assembyInfo.cchBuf = 512; 
      assembyInfo.currentAssemblyPath = new String('\0', 
       assembyInfo.cchBuf) ; 

      IAssemblyCache assemblyCache = null; 

      // Get IAssemblyCache pointer 
      IntPtr hr = GacApi.CreateAssemblyCache(out assemblyCache, 0); 
      if (hr == IntPtr.Zero) 
      { 
       hr = assemblyCache.QueryAssemblyInfo(1, assemblyName, ref assembyInfo); 
       if (hr != IntPtr.Zero) 
       { 
        Marshal.ThrowExceptionForHR(hr.ToInt32()); 
       } 
      } 
      else 
      { 
       Marshal.ThrowExceptionForHR(hr.ToInt32()); 
      } 
      return assembyInfo.currentAssemblyPath; 
     } 
    } 
} 

Uso QueryAssemblyInfo método.

+0

HRESULT se define como un entero de 32 bits, por lo que CreateAssemblyCache y QueryAssemblyInfo deben devolver int en lugar de IntPtr. –

+0

¿Para qué son los 'Dummy1()', 'Dummy2()' ... para? – BanksySan

12

Hacer una Assembly.LoadFrom y comprobar GlobalAssemblyCache

testAssembly = Assembly.LoadFrom(dllname); 

if (!testAssembly.GlobalAssemblyCache) 
{ 
    // not in gac 
} 
+0

¿Por qué el voto a favor? – dvallejo

+0

No veo ninguna razón para un voto a la baja. Para mí, esta parece ser la respuesta más elegante hasta ahora, ya que no requiere cosas complejas con Fusion/COM. Esto también debería funcionar si está cargando ensamblados en el [contexto de solo reflejo] (http://msdn.microsoft.com/en-us/library/ms172331.aspx) – derabbink

0

Sé que esto es una cuestión de edad, sino por causa de nuevos viajeros ...

Tenemos una biblioteca de fusión (gratis) disponible para descarga en que hace exactamente esto. Divulgación: Sí, estoy afiliado. No, no recibiré dinero si lo descarga. ;-)

Cuestiones relacionadas