Obtenga programáticamente el número de versión de una DLL

151

¿Es posible obtener el número de versión mediante programación desde cualquier DLL .NET?

Si es así, ¿cómo?

JL
fuente
10
No puedo creer que esto se haya pedido hace 6 minutos, ¡estaba a punto de preguntar lo mismo!
tpower
2
revise este enlace también para la versión de incremento automático - blog.mbcharbonneau.com/2007/03/13/…
JL.

Respuestas:

119
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Version ver = assembly.GetName().Version;

Importante: Cabe señalar que esta no es la mejor respuesta a la pregunta original. No olvides leer más en esta página.

Kris
fuente
28
Esto carga MyAssembly.dll en el dominio de aplicación en ejecución ... mala idea.
staafl
12
Recomiendo Assemblyname.GetAssemblyNameevitar estos problemas
staafl
77
cargar un ensamblado en el dominio de aplicación es lento, irreversible (no se puede descargar sin eliminar el dominio), requiere permisos y puede causar efectos secundarios, como la ejecución de beforefieldinitinicializadores de tipo, y simplemente no es necesario en este caso. ¿Son suficientes estas razones?
staafl
77
@staafl: sí; no solo para mí, sino también para todos los que lean esta página en el futuro.
Kris
66
FileVersionInfo.GetVersionInfo("foo.dll").FileVersionhace bien el trabajo y no carga el dll en la aplicación.
Jack
181

Esto funciona si el dll es .net o Win32 . Los métodos de reflexión solo funcionan si el dll es .net. Además, si usa la reflexión, tiene la sobrecarga de cargar todo el dll en la memoria. El siguiente método no carga el ensamblaje en la memoria.

// Get the file version.
FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(@"C:\MyAssembly.dll");

// Print the file name and version number.
Console.WriteLine("File: " + myFileVersionInfo.FileDescription + '\n' +
                  "Version number: " + myFileVersionInfo.FileVersion);

De: http://msdn.microsoft.com/en-us/library/system.diagnostics.fileversioninfo.fileversion.aspx

fuente original

Ben Anderson
fuente
55
Me gusta esto. ¿Por qué te molestas en cargar el dll y luego usar la reflexión solo para obtener la versión, cuando todo lo que realmente quieres hacer es esto?
aggieNick02
@ben, ¿podrías editar la publicación? Vi que había perdido -1 repetición al agregar un voto negativo, que no recuerdo haber hecho. no me dejará cambiarlo, a menos que edites la publicación. ¡salud!
Luke Duddridge el
9
Si desea asegurarse de obtener el ejecutable / DLL en realidad actualmente en uso: en lugar de un nombre de archivo estático ( @"C:\MyAssembly.dll"arriba), puede utilizar System.Reflection.Assembly.GetExecutingAssembly().Location(o si un archivo DLL: Assembly.GetAssembly(typeof(AClassInTheDll)).Location)
Conrad
44
Es la diferencia entre los atributos AssemblyVersion y AssemblyFileVersion. AssemblyFileVersion se estampa de manera tal que la API de Windows puede obtener el valor. AssemblyVersion es parte del nombre seguro y no es necesariamente lo mismo que AssemblyFileVersion.
daughey
51

En primer lugar, hay dos posibles 'versiones' que pueden interesarle:

  • Versión del archivo del sistema de archivos de Windows, aplicable a todos los archivos ejecutables

  • Versión de compilación de ensamblado, que el compilador incrusta en un ensamblado .NET (obviamente solo se aplica a los archivos dll y exe de ensamblado .NET)

En el primer caso, debe usar la respuesta de Ben Anderson; en el último caso, use AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Versiono la respuesta de Tataro, en caso de que el código haga referencia al ensamblado.

Tenga en cuenta que puede ignorar todas las respuestas que usan .Load()/ .LoadFrom()métodos, ya que estos realmente cargan el ensamblado en el dominio de aplicación actual, lo que es análogo a cortar un árbol para ver qué edad tiene.

staafl
fuente
32

Aquí hay una buena manera de usar un poco de reflexión para obtener una versión de un archivo DLL que contenga una clase particular:

var ver = System.Reflection.Assembly.GetAssembly(typeof(!Class!)).GetName().Version;

¡Solo reemplace! ¡Clase! con el nombre de una clase que se define en la DLL de la que desea obtener la versión.

Este es mi método preferido porque si muevo las DLL para diferentes implementaciones, no tengo que cambiar la ruta del archivo.

Totero
fuente
3
Tenga en cuenta que esto solo funciona si el ensamblaje en cuestión está referenciado estáticamente por el actual.
staafl
2
Esta es la mejor respuesta ya que el DLL no es necesariamente la entrada de montaje ni siquiera el ensamblaje esto se llama desde
CAD Bloke
1
Consulte stackoverflow.com/a/909583/492 para obtener diferentes tipos de información de versión. p.ej.FileVersionInfo
CAD bloke
22

Para obtenerlo para el ensamblaje que se inició (winform, aplicación de consola, etc.)

using System.Reflection;
...
Assembly.GetEntryAssembly().GetName().Version
Agent_9191
fuente
66
GetExecutingAssembly () también podría ayudar.
Bolt Thunder
10

Kris, su versión funciona muy bien cuando necesita cargar el ensamblado desde el archivo DLL real (¡y si el archivo DLL está ahí!), Sin embargo, uno obtendrá un error no deseado si el archivo DLL está incrustado (es decir, no es un archivo sino un archivo incrustado DLL)

La otra cosa es que si uno usa un esquema de versiones con algo como " 1.2012.0508.0101 ", cuando uno obtiene la cadena de versión, obtendrá " 1.2012.518.101 "; tenga en cuenta los ceros que faltan .

Entonces, aquí hay algunas funciones adicionales para obtener la versión de una DLL (incrustada o desde el archivo DLL):

    public static System.Reflection.Assembly GetAssembly(string pAssemblyName)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if (string.IsNullOrEmpty(pAssemblyName)) { return tMyAssembly; }
        tMyAssembly = GetAssemblyEmbedded(pAssemblyName);
        if (tMyAssembly == null) { GetAssemblyDLL(pAssemblyName); }

        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)


    public static System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if(string.IsNullOrEmpty(pAssemblyDisplayName)) { return tMyAssembly; }
        try //try #a
        {
            tMyAssembly = System.Reflection.Assembly.Load(pAssemblyDisplayName);
        }// try #a
        catch (Exception ex)
        {
            string m = ex.Message;
        }// try #a
        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)


    public static System.Reflection.Assembly GetAssemblyDLL(string pAssemblyNameDLL)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if (string.IsNullOrEmpty(pAssemblyNameDLL)) { return tMyAssembly; }
        try //try #a
        {
            if (!pAssemblyNameDLL.ToLower().EndsWith(".dll")) { pAssemblyNameDLL += ".dll"; }
            tMyAssembly = System.Reflection.Assembly.LoadFrom(pAssemblyNameDLL);
        }// try #a
        catch (Exception ex)
        {
            string m = ex.Message;
        }// try #a
        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyFile(string pAssemblyNameDLL)


    public static string GetVersionStringFromAssembly(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssembly(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


    public static string GetVersionString(Version pVersion)
    {
        string tVersion = "Unknown";
        if (pVersion == null) { return tVersion; }
        tVersion = GetVersionString(pVersion.ToString());
        return tVersion;
    }//string GetVersionString(Version pVersion)


    public static string GetVersionString(string pVersionString)
    {
        string tVersion = "Unknown";
        string[] aVersion;

        if (string.IsNullOrEmpty(pVersionString)) { return tVersion; }
        aVersion = pVersionString.Split('.');
        if (aVersion.Length > 0) { tVersion = aVersion[0]; }
        if (aVersion.Length > 1) { tVersion += "." + aVersion[1]; }
        if (aVersion.Length > 2) { tVersion += "." + aVersion[2].PadLeft(4, '0'); }
        if (aVersion.Length > 3) { tVersion += "." + aVersion[3].PadLeft(4, '0'); }

        return tVersion;
    }//string GetVersionString(Version pVersion)


    public static string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssemblyEmbedded(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


    public static string GetVersionStringFromAssemblyDLL(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssemblyDLL(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)
MacSpudster
fuente
2
var versionAttrib = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
Invencible
fuente
2

La respuesta de @Ben resultó ser útil para mí. Pero necesitaba verificar la versión del producto, ya que era el incremento principal que ocurría en mi software y seguía el control de versiones semántico.

myFileVersionInfo.ProductVersion

Este método cumplió mis expectativas.

Actualización: en lugar de mencionar explícitamente la ruta dll en el programa (según sea necesario en la versión de producción), podemos obtener la versión del producto usando Assembly.

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fileVersionInfo =FileVersionInfo.GetVersionInfo(assembly.Location); 
string ProdVersion= fileVersionInfo.ProductVersion;
Prasan Dutt
fuente
Nota: si la versión contiene un asterisco para el valor de incremento automático, este método devolverá el asterisco en lugar del número real generado (es decir, no funciona si coloca 1.0. * En la información de su ensamblaje).
Ronen Ness
¡Si! Sin embargo, elegí la automatización de Jeniks para la actualización de la versión, por lo que el ensamblaje siempre tiene una combinación perfecta de la versión dll.
Prasan Dutt
1

Puede usar los métodos System.Reflection.Assembly.Load * () y luego tomar su información de ensamblaje.

Ariel
fuente
0

Si bien la pregunta original puede no haber sido específica para un servicio web, aquí hay un testWebService completo que puede agregar para mostrar una respuesta no almacenada en caché del servicio web más la versión del archivo. Usamos la versión de archivo en lugar de la versión de ensamblaje porque queremos conocer una versión, pero con todas las versiones de ensamblaje 1.0.0.0, el sitio web se puede parchar fácilmente (¡el vínculo de firma y demanda aún está activo!). Reemplace @ Class @ con el nombre del controlador de API web en el que está incrustado este servicio. Es bueno para ir / nogo en un servicio web más una verificación de versión rápida.

  [Route("api/testWebService")]
  [AllowAnonymous]
  [HttpGet]
  public HttpResponseMessage TestWebService()
  {
      HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.OK);
      string loc = Assembly.GetAssembly(typeof(@Class@)).Location;
      FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(loc);
      responseMessage.Content = new StringContent($"<h2>The XXXXX web service GET test succeeded.</h2>{DateTime.Now}<br/><br/>File Version: {versionInfo.FileVersion}");
      responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
      Request.RegisterForDispose(responseMessage);
      return responseMessage;
  }

También encontré que era necesario agregar lo siguiente a web.config en la configuración para que sea realmente anónimo

<location path="api/testwebservice">
    <system.web>
        <authorization>
            <allow users="*" />
        </authorization>
    </system.web>
</location>
Wray Smallwood
fuente