Usando el número de versión de la aplicación Web de un ensamblado (ASP.NET/C#)


¿Cómo obtengo el número de versión de la aplicación web que llama en un ensamblado referenciado?

He intentado usar el Sistema.Reflexión.Asamblea.GetCallingAssembly().getName () pero solo me da el ensamblado compilado dinámicamente (devolviendo un número de versión de 0.0.0.0).

ACTUALIZACIÓN: En mi caso necesitaba una solución que no requiriera una referencia a una clase dentro del ensamblado de la aplicación web. La respuesta de Jason a continuación (marcada como aceptada) cumple este requisito-a muchos otros presentados aquí no lo hacen.

Author: David Duffett, 2009-04-16

11 answers

Aquí hay un código que uso que admite obtener el ensamblado "principal" de la aplicación desde aplicaciones Web o no web, luego puede usar getName().Versión para obtener la versión.

Primero intenta GetEntryAssembly() para aplicaciones no web. Esto devuelve null bajo ASP.NET. Luego mira HttpContext.Actual para determinar si se trata de una aplicación web. A continuación, utiliza el tipo del HttpHandler actual-pero el ensamblado de este tipo podría ser un ASP.NET asamblea si la llamada se realiza desde con un ASPX, por lo que atraviesa la cadena BaseType de HttpHandler hasta que encuentra un tipo que no está en el espacio de nombres que ASP.NET utiliza para sus tipos generados ("ASP"). Esto generalmente será un tipo en su asamblea principal (eg. La página en su archivo de código detrás). Entonces podemos usar el Ensamblaje de ese Tipo. Si todo lo demás falla entonces vuelve a GetExecutingAssembly ().

Todavía Hay problemas potenciales con este enfoque, pero funciona en nuestras aplicaciones.

    private const string AspNetNamespace = "ASP";

    private static Assembly getApplicationAssembly()
    {
        // Try the EntryAssembly, this doesn't work for ASP.NET classic pipeline (untested on integrated)
        Assembly ass = Assembly.GetEntryAssembly();

        // Look for web application assembly
        HttpContext ctx = HttpContext.Current;
        if (ctx != null)
            ass = getWebApplicationAssembly(ctx);

        // Fallback to executing assembly
        return ass ?? (Assembly.GetExecutingAssembly());
    }

    private static Assembly getWebApplicationAssembly(HttpContext context)
    {
        Guard.AgainstNullArgument(context);

        object app = context.ApplicationInstance;
        if (app == null) return null;

        Type type = app.GetType();
        while (type != null && type != typeof(object) && type.Namespace == AspNetNamespace)
            type = type.BaseType;

        return type.Assembly;
    }

ACTUALIZAR: He rodado este código de en un pequeño proyecto en GitHub y NuGet.

 48
Author: Jason Duffett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-12 11:31:44

Encuentro que la forma más simple de obtener la versión de su ensamblaje "principal" (en lugar del dinámico) es:

typeof(MyMainClass).Assembly.GetName().Version

Use su clase de nivel superior, que no es probable que alguna vez "cambie su significado" o que sea reemplazada como parte de un esfuerzo de refactorización, como MyMainClass. Usted sabe en qué asamblea se define esta misma clase y ya no puede haber confusión en cuanto a dónde viene el número de versión.

 33
Author: Yodan Tauber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-02 06:55:07

Prefiero la Web.Configuración para almacenar la versión actual del sitio.

También puede intentar crear un AssemblyInfo.archivo cs en la raíz de la aplicación web que tiene lo siguiente:

using System.Reflection;
using System.Runtime.CompilerServices;
...
[assembly: AssemblyVersion("1.0.*")]
...

Luego accede al valor a través del código como este:

System.Reflection.Assembly.GetExecutingAssembly()

Aquí hay más informaiton sobre la clase AssemblyInfo.

 26
Author: Random Developer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-27 19:44:50

Para agregar a los respondedores que ya han publicado. Para obtener la versión ensamblada en un ASP.Net aplicación web necesita colocar un método en el código detrás del archivo similar a:

protected string GetApplicationVersion() {
    return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}

En la página ASPX desea mostrar el número de versión simplemente coloque:

<%= GetApplicationVersion() %>
 14
Author: Amir Khawaja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 21:05:49

Solo en caso de que alguien todavía esté interesado; esto debería hacer el truco y debería ser un poco más seguro que simplemente tomar el BaseType de ApplicationInstance para tener en sus manos el Global.implementación de asax.

Global.asax siempre se compila en el mismo ensamblado que los atributos de ensamblado de AssemblyInfo.cs, por lo que esto debería funcionar para todas las aplicaciones web que definen un Global.asax.

Para aquellos que no definen su propio Global.asax, volverá a la versión del tipo global_asax generado, que siempre es 0.0.0.0, y para aplicaciones que no son aplicaciones web, simplemente devolverá ninguna versión en absoluto.

Bonus; usando la clase BuildManager no requiere una instancia HttpContext activa, lo que significa que también debería poder usar esto desde el código de inicio de la aplicación.

public static Version GetHttpApplicationVersion() {
  Type lBase = typeof(HttpApplication);
  Type lType = BuildManager.GetGlobalAsaxType();

  if (lBase.IsAssignableFrom(lType))
  {
    while (lType.BaseType != lBase) { lType = lType.BaseType; }
    return lType.Assembly.GetName().Version;
  }
  else
  {
    return null;
  }
}
 8
Author: Ron Otten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-28 07:16:39

HttpContext.Actual.ApplicationInstance se deriva de la clase en el global.asax.cs. Puede hacer lo siguiente

 var instance = HttpContext.Current.ApplicationInstance;
 Assembly asm = instance.GetType().BaseType.Assembly;
 System.Version asmVersion = asm.GetName().Version;

Funciona tanto en ASP.NET (ASPX) y ASP.NET MVC

 6
Author: Andrei Schneider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-24 15:26:41

Me encontré con un problema similar, y pensé que podría encontrar la solución útil.

Necesitaba reportar la versión actual de la aplicación (de un proyecto de aplicación web) desde un control de servidor personalizado, donde el control de servidor estaba contenido en una biblioteca diferente. El problema era que los" más fáciles " de ensamblar no proporcionaban el ensamblaje correcto.

  • Assembly.GetExecutingAssembly() devolvió el ensamblado que contenía el control; no el ensamblado de la aplicación.
  • Assembly.GetCallingAssembly() devuelto diferentes ensamblajes dependiendo de dónde estaba en el árbol de llamadas; generalmente Sistema.Web, y a veces el conjunto que contiene el control.
  • Assembly.GetEntryAssembly() devuelto null.
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assembly recupera el ensamblado de un frame en el stack trace at index idx; sin embargo, además de ser poco elegante, costoso y propenso a errores de cálculo en el frame index, es posible que el stack trace no contenga ninguna llamada al ensamblado de la aplicación.
  • Assembly.GetAssembly(Page.GetType()) me anotó el App_Web_@#$@#$%@ ensamblado que contiene la página generada dinámicamente. Por supuesto, la página dinámica hereda una clase de mi ensamblaje de aplicación, por lo que condujo a la solución final:

Assembly.GetAssembly(Page.GetType().BaseType)

Con la referencia de ensamblaje en la mano, puede perforar la versión a través de su nombre:

var version = Assembly.GetAssembly(Page.GetType().BaseType)
                      .GetName()
                      .Version;

Ahora, esta solución funciona porque tenía una referencia a un tipo del ensamblaje de la aplicación. No usamos ninguna página que no herede de un código detrás, por lo que sucede que es efectivo para nosotros, pero su kilometraje puede variar si las prácticas de codificación de su organización son diferentes.

Feliz codificación!

 3
Author: kbrimington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-18 14:33:41
Version version = new Version(Application.ProductVersion);
string message = version.ToString();
 2
Author: noname,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-25 08:42:22

Algo de información aquí: http://www.velocityreviews.com/forums/showpost.php?p=487050&postcount=8

En asp.net 2.0 cada página está integrada en su propio ensamblado, por lo que solo el dll el AssemblyInfo.cs está integrado en will devuelve la respuesta correcta. solo tiene que añadir un método estático a AssemblyInfo.cs que devuelve la información de la versión y llama este método de sus otras páginas.

Bruce bruce (sqlwork.com)

Pero escribí un método simple para hacer que:

    public static string GetSystemVersion(HttpServerUtility server)
    {
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.Load(server.MapPath("~/web.config"));
        System.Xml.XmlNamespaceManager ns = new System.Xml.XmlNamespaceManager(doc.NameTable);
        ns.AddNamespace("bla", "http://schemas.microsoft.com/.NetConfiguration/v2.0");

        System.Xml.XmlNode node = doc.SelectSingleNode("/bla:configuration/bla:system.web/bla:authentication/bla:forms[@name]", ns);

        string projectName = "";
        if (node != null && node.Attributes != null && node.Attributes.GetNamedItem("name") != null)
            projectName = node.Attributes.GetNamedItem("name").Value; //in my case, that value is identical to the project name (projetname.dll)
        else
            return "";

        Assembly assembly = Assembly.Load(projectName);
        return assembly.GetName().Version.ToString();
    }
 1
Author: Seiti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-10 19:30:53

Si está buscando esto desde un control web, un truco es encontrar el tipo de la página detrás del código (es decir. la clase que hereda del Sistema.Web.UI.Pagina). Esto es normalmente en la asamblea web del consumidor.

Type current, last;
current = Page.GetType();
do
{
    last = current;
    current = current.BaseType;
} while (current != null && current != typeof(System.Web.UI.Page));
return last;

Espero que haya una mejor manera.

 1
Author: Matt Woodard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-25 17:38:10

La pregunta dice sin referencia (instancias) no dijo (originalmente) sin conocimiento de los tipos de aplicaciones web.

EDIT el OP aclaró que sí realmente no requieren conocimiento de los tipos dentro del ensamblado web que llama, por lo que la respuesta es apropiada. Sin embargo, consideraría seriamente la refactorización de una solución tal que la versión se pase al otro conjunto.

Para la mayoría de las personas en este escenario si conoce la costumbre HttpApplication type:

 typeof(MyHttpApplication).Assembly.GetName().Version

Y si solo tiene un tipo generado dinámico:

 typeof(DynamiclyGeneratedTypeFromWebApp).BaseType.Assembly.GetName().Version

Deja de votarme por esta respuesta :)

 1
Author: Tom Deloford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-14 23:09:00