2008-10-09 10 views
52

En mi programa, ¿cómo puedo leer las propiedades establecidas en AssemblyInfo.cs:Cómo leer el montaje atributos

[assembly: AssemblyTitle("My Product")] 
[assembly: AssemblyDescription("...")] 
[assembly: AssemblyConfiguration("")] 
[assembly: AssemblyCompany("Radeldudel inc.")] 
[assembly: AssemblyProduct("My Product")] 
[assembly: AssemblyCopyright("Copyright @ me 2008")] 
[assembly: AssemblyTrademark("")] 
[assembly: AssemblyCulture("")] 

me gustaría mostrar algunos de estos valores para el usuario de mi programa, por lo que Me gustaría saber cómo cargarlos desde el programa principal y desde ensamblajes komponent que estoy usando.

Respuesta

51

Esto es bastante fácil. Tienes que usar la reflexión. Necesita una instancia de Assembly que represente el ensamblado con los atributos que desea leer. Una manera fácil de conseguir esto es hacer:

typeof(MyTypeInAssembly).Assembly 

entonces usted puede hacer esto, por ejemplo:

object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false); 

AssemblyProductAttribute attribute = null; 
if (attributes.Length > 0) 
{ 
    attribute = attributes[0] as AssemblyProductAttribute; 
} 

referencia a attribute.Product ahora le dará el valor que ha pasado al atributo en su AssemblyInfo. cs. Por supuesto, si el atributo que busca puede ocurrir más de una vez, puede obtener varias instancias en la matriz devuelta por GetCustomAttributes, pero esto no suele ser un problema para los atributos de nivel de ensamblaje, como los que espera recuperar.

+4

También puede usar Assembly.GetExecutingAssembly(). GetCustomAttributes() para obtener los atributos del ensamblado que se está ejecutando actualmente. – jop

+0

Tenga en cuenta que si está leyendo atributos para un ensamblaje que no está cargado, el proceso de carga no se puede deshacer a menos que se use un AppDomain separado y luego se descargue. –

+4

GetExecutingAssembly no siempre da lo que desea (por ejemplo, puede devolver el depurador si el depurador inició su aplicación). –

10

Ok, tal vez un poco desactualizado ahora para la pregunta original, pero lo presentaré para futuras referencias de todos modos.

Si desea hacerlo desde dentro de la propia asamblea a continuación, utilizar el siguiente:

using System.Runtime.InteropServices; 
using System.Reflection; 

object[] customAttributes = this.GetType().Assembly.GetCustomAttributes(false); 

A continuación, puede iterar a través de todos los atributos personalizados para encontrar la (s) que necesite, por ejemplo,

foreach (object attribute in customAttributes) 
{ 
    string assemblyGuid = string.Empty;  

    if (attribute.GetType() == typeof(GuidAttribute)) 
    { 
    assemblyGuid = ((GuidAttribute) attribute).Value; 
    break; 
    } 
} 
+0

Me gustaría usar el Copyright. No está en la lista de atributos paralelos a GuidAttribute en http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.aspx – AnneTheAgile

+0

(lo siento, no puedo editar mi otro comentario) Esto es genial, Veo System.Reflection.Assembly * tiene todos los atributos habituales y muchos que no conocía. http://msdn.microsoft.com/en-us/library/system.attribute.aspx Para usar el Copyright, funcionó; aCopyright = ((AssemblyCopyrightAttribute) attribute) .Copyright.ToString(); – AnneTheAgile

12

He creado este método de extensión que utiliza LINQ:

public static T GetAssemblyAttribute<T>(this System.Reflection.Assembly ass) where T : Attribute 
{ 
    object[] attributes = ass.GetCustomAttributes(typeof(T), false); 
    if (attributes == null || attributes.Length == 0) 
     return null; 
    return attributes.OfType<T>().SingleOrDefault(); 
} 

y que convenientemente se puede utilizar de esa manera:

var attr = targetAssembly.GetAssemblyAttribute<AssemblyDescriptionAttribute>(); 
if(attr != null) 
    Console.WriteLine("{0} Assembly Description:{1}", Environment.NewLine, attr.Description); 
+0

Un excelente método de utilidad. Una sugerencia rápida para aquellos interesados ​​en obtener la versión de un ensamblaje. Uso: assembly.GetAssemblyAttribute () (detalles: http://stackoverflow.com/questions/1144525/getcustomattribute-returns-null-for-assemblyversionattribute) – xDisruptor

4

bien, estoy trataron de ir a través de muchos recursos para encontrar un método para extraer los atributos .dll para un Assembly.LoadFrom(path). Pero desafortunadamente no pude encontrar ningún buen recurso. Y esta pregunta fue el resultado más alto para buscar en c# get assembly attributes (al menos para mí) Así que pensé en compartir mi trabajo.

Escribí siguiendo un sencillo programa de consola para recuperar atributos de ensamblaje general después de muchas horas de lucha. Aquí proporcioné el código para que cualquiera pueda usarlo para futuros trabajos de referencia.

Yo uso CustomAttributes propiedad para esto.Siéntase libre de comentar en este enfoque

Código:

using System; 
using System.Reflection; 

namespace MetaGetter 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Assembly asembly = Assembly.LoadFrom("Path to assembly"); 

      foreach (CustomAttributeData atributedata in asembly.CustomAttributes) 
      { 
       Console.WriteLine(" Name : {0}",atributedata.AttributeType.Name); 

       foreach (CustomAttributeTypedArgument argumentset in atributedata.ConstructorArguments) 
       { 
        Console.WriteLine(" >> Value : {0} \n" ,argumentset.Value); 
       } 
      } 

      Console.ReadKey(); 
     } 
    } 
} 

Ejemplo de salida:

Name : AssemblyTitleAttribute 
    >> Value : "My Product" 
+1

Me gustaría señalar que la propiedad ['CustomAttributes'] (https : //msdn.microsoft.com/en-us/library/system.reflection.assembly.customattributes%28v=vs.110%29.aspx) solo está disponible desde .NET 4.5 y superior. En .NET 4.0 y versiones posteriores, el método ['GetCustomAttributesData()'] (https://msdn.microsoft.com/en-us/library/system.reflection.assembly.getcustomattributesdata%28v=vs.100%29.aspx) está disponible como una alternativa. –

2

utilizo este:

public static string Title 
{ 
    get 
    { 
     return GetCustomAttribute<AssemblyTitleAttribute>(a => a.Title); 
    } 
} 

para referencia:

using System; 
using System.Reflection; 
using System.Runtime.CompilerServices; 



namespace Extensions 
{ 


    public static class AssemblyInfo 
    { 


     private static Assembly m_assembly; 

     static AssemblyInfo() 
     { 
      m_assembly = Assembly.GetEntryAssembly(); 
     } 


     public static void Configure(Assembly ass) 
     { 
      m_assembly = ass; 
     } 


     public static T GetCustomAttribute<T>() where T : Attribute 
     { 
      object[] customAttributes = m_assembly.GetCustomAttributes(typeof(T), false); 
      if (customAttributes.Length != 0) 
      { 
       return (T)((object)customAttributes[0]); 
      } 
      return default(T); 
     } 

     public static string GetCustomAttribute<T>(Func<T, string> getProperty) where T : Attribute 
     { 
      T customAttribute = GetCustomAttribute<T>(); 
      if (customAttribute != null) 
      { 
       return getProperty(customAttribute); 
      } 
      return null; 
     } 

     public static int GetCustomAttribute<T>(Func<T, int> getProperty) where T : Attribute 
     { 
      T customAttribute = GetCustomAttribute<T>(); 
      if (customAttribute != null) 
      { 
       return getProperty(customAttribute); 
      } 
      return 0; 
     } 



     public static Version Version 
     { 
      get 
      { 
       return m_assembly.GetName().Version; 
      } 
     } 


     public static string Title 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyTitleAttribute>(
        delegate(AssemblyTitleAttribute a) 
        { 
         return a.Title; 
        } 
       ); 
      } 
     } 

     public static string Description 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyDescriptionAttribute>(
        delegate(AssemblyDescriptionAttribute a) 
        { 
         return a.Description; 
        } 
       ); 
      } 
     } 


     public static string Product 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyProductAttribute>(
        delegate(AssemblyProductAttribute a) 
        { 
         return a.Product; 
        } 
       ); 
      } 
     } 


     public static string Copyright 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyCopyrightAttribute>(
        delegate(AssemblyCopyrightAttribute a) 
        { 
         return a.Copyright; 
        } 
       ); 
      } 
     } 



     public static string Company 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyCompanyAttribute>(
        delegate(AssemblyCompanyAttribute a) 
        { 
         return a.Company; 
        } 
       ); 
      } 
     } 


     public static string InformationalVersion 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyInformationalVersionAttribute>(
        delegate(AssemblyInformationalVersionAttribute a) 
        { 
         return a.InformationalVersion; 
        } 
       ); 
      } 
     } 



     public static int ProductId 
     { 
      get 
      { 
       return GetCustomAttribute<AssemblyProductIdAttribute>(
        delegate(AssemblyProductIdAttribute a) 
        { 
         return a.ProductId; 
        } 
       ); 
      } 
     } 


     public static string Location 
     { 
      get 
      { 
       return m_assembly.Location; 
      } 
     } 

    } 

} 
+0

int public static ProductId { obtener { retorno GetCustomAttribute ( delegado (AssemblyProductIdAttribute a) { a.ProductId retorno; } ); }} Aquí, ' 'Error -> El tipo o espacio de nombres 'AssemblyProductIdAttribute AssemblyProductIdAttribute' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) – Pritam

+0

Pritam: Te estás perdiendo el Sistema de espacio de nombres. Reflexión (usando System.Reflection;), o estás en una edición/versión de framework extraño. https://msdn.microsoft.com/en-us/library/system.reflection.assemblyproductattribute(v=vs.110).aspx –

+0

__using System.Reflection__ está incluido en el código, puedo usar fácilmente otras funciones. Ninguno de ellos da ningún error. Además, Framework también es correcto. – Pritam