2008-10-09 23 views
20

Una función pequeña de un programa grande examina los ensamblajes en una carpeta y reemplaza los ensamblajes desactualizados con las versiones más recientes. Para lograr esto, necesita leer los números de versión de los archivos de ensamblaje existentes sin cargarlos en el proceso de ejecución.¿Cómo obtengo la versión de un ensamblaje sin cargarlo?

+0

¿En qué idioma estás codificando? –

+0

@RB: el idioma no importa, porque uno usaría las mismas clases para obtener la información. –

+0

Necesita hacer que la respuesta de Jop o Jop sea la correcta. Yo los votaría hasta un millón si pudiera. He querido saber cómo hacer esto por años. – MusiGenesis

Respuesta

32

Encontré el siguiente in this article.

using System.Reflection; 
using System.IO; 

... 

// Get current and updated assemblies 
AssemblyName currentAssemblyName = AssemblyName.GetAssemblyName(currentAssemblyPath); 
AssemblyName updatedAssemblyName = AssemblyName.GetAssemblyName(updatedAssemblyPath); 

// Compare both versions 
if (updatedAssemblyName.Version.CompareTo(currentAssemblyName.Version) <= 0) 
{ 
    // There's nothing to update 
    return; 
} 

// Update older version 
File.Copy(updatedAssemblyPath, currentAssemblyPath, true); 
+0

mierda. Como siempre para mí, esto no funciona en el Marco Compacto. AssemblyName está allí, pero AssemblyName.GetAssemblyName no lo está. – MusiGenesis

+0

Un viejo truco que solía usar (para escanear a través de ensamblajes de complementos) era crear un AppDomain de zona de pruebas, cargarlos en eso y luego cerrar el AppDomain cuando había terminado. No estoy seguro acerca de CF, sin embargo. –

+0

¿Tiene un ejemplo de código para el enfoque de recinto de seguridad? – MusiGenesis

9

Usa AssemblyName.GetAssemblyName("assembly.dll");, luego analiza el nombre. De acuerdo con MSDN:

esto sólo funcionará si el archivo contiene un manifiesto de ensamblado. Este método hace que el archivo se abra y se cierre, pero el conjunto no es agregado a este dominio.

+0

Estoy tratando de no pensar en todos los hacks que he implementado tratando de obtener un número de versión sin cargar el archivo. Yeesh. – MusiGenesis

11

función de los archivos, una opción podría ser FileVersionInfo - es decir,

FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(path) 
string ver = fvi.FileVersion; 

El problema es que esto depende del código que tiene el atributo [AssemblyFileVersion], y que coincide con el atributo [AssemblyVersion].

Creo que antes vería las opciones de AssemblyName sugeridas por otros.

+1

La comparación de FileVersionInfo así podría ser útil también. Una actualización de una biblioteca que corrige errores pero no cambia la API podría tener la misma versión de ensamblado pero debería tener una versión de archivo diferente. Entonces, en muchos casos, AssemblyFileVersion puede ser el que desee verificar. –

+0

Consejo: el uso de FileVersionInfo vive en el espacio de nombres de System.Diagnostics que necesitaría importar. –

+0

@eithe, aunque para ser justos, puede presionar ctrl +. (con el foco en un tipo no resuelto) y el IDE lo encontrará y lo agregará para usted ...entonces no necesitas memorizar espacios de nombres –

0

Solo para el registro: Así es cómo obtener la versión del archivo en C# .NET Compact Framework. Básicamente es de OpenNETCF, pero bastante más corto y está desactivado, por lo que puede copiarse. Espero que ayude ...

public static Version GetFileVersionCe(string fileName) 
{ 
    int handle = 0; 
    int length = GetFileVersionInfoSize(fileName, ref handle); 
    Version v = null; 
    if (length > 0) 
    { 
     IntPtr buffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(length); 
     if (GetFileVersionInfo(fileName, handle, length, buffer)) 
     { 
      IntPtr fixedbuffer = IntPtr.Zero; 
      int fixedlen = 0; 
      if (VerQueryValue(buffer, "\\", ref fixedbuffer, ref fixedlen)) 
      { 
       byte[] fixedversioninfo = new byte[fixedlen]; 
       System.Runtime.InteropServices.Marshal.Copy(fixedbuffer, fixedversioninfo, 0, fixedlen); 
       v = new Version(
        BitConverter.ToInt16(fixedversioninfo, 10), 
        BitConverter.ToInt16(fixedversioninfo, 8), 
        BitConverter.ToInt16(fixedversioninfo, 14), 
        BitConverter.ToInt16(fixedversioninfo, 12)); 
      } 
     } 
     Marshal.FreeHGlobal(buffer); 
    } 
    return v; 
} 

[DllImport("coredll", EntryPoint = "GetFileVersionInfo", SetLastError = true)] 
private static extern bool GetFileVersionInfo(string filename, int handle, int len, IntPtr buffer); 
[DllImport("coredll", EntryPoint = "GetFileVersionInfoSize", SetLastError = true)] 
private static extern int GetFileVersionInfoSize(string filename, ref int handle); 
[DllImport("coredll", EntryPoint = "VerQueryValue", SetLastError = true)] 
private static extern bool VerQueryValue(IntPtr buffer, string subblock, ref IntPtr blockbuffer, ref int len); 
Cuestiones relacionadas