2008-10-09 11 views
52

Dans mon programme, comment puis-je lire les propriétés définies dans AssemblyInfo.cs:Comment lire l'ensemble des attributs

[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("")] 

Je voudrais afficher certaines de ces valeurs à l'utilisateur de mon programme, je J'aimerais savoir comment les charger à partir du programme principal et des assemblages komponent que j'utilise.

Répondre

51

Ceci est relativement facile. Vous devez utiliser la réflexion. Vous avez besoin d'une instance de Assembly qui représente l'assembly avec les attributs que vous voulez lire. Un moyen facile d'obtenir cela est de faire:

typeof(MyTypeInAssembly).Assembly 

Ensuite, vous pouvez le faire, par exemple:

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

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

Référencer attribute.Product vous donnera maintenant la valeur fournie à l'attribut dans votre AssemblyInfo. cs. Bien sûr, si l'attribut que vous recherchez peut apparaître plusieurs fois, vous pouvez obtenir plusieurs instances dans le tableau renvoyé par GetCustomAttributes, mais ce n'est généralement pas un problème pour les attributs de niveau assembly comme ceux que vous espérez récupérer.

+4

Vous pouvez également utiliser Assembly.GetExecutingAssembly(). GetCustomAttributes() pour obtenir les attributs de l'assembly en cours d'exécution. – jop

+0

Notez que si vous lisez des attributs pour un assembly qui n'est pas chargé, le processus de chargement ne peut pas être annulé à moins qu'un AppDomain distinct soit utilisé puis déchargé. –

+4

GetExecutingAssembly ne donne pas toujours ce que vous voulez (par exemple, il peut retourner le débogueur si le débogueur a démarré votre application). –

10

Ok, peut-être un peu démodé maintenant pour la question originale mais je vais vous le présenter pour référence future de toute façon.

Si vous voulez le faire à l'intérieur de l'assemblée elle-même alors utiliser les éléments suivants:

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

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

Vous pouvez ensuite parcourir tous les attributs personnalisés pour trouver celle (s) dont vous avez besoin par exemple

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

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

Je voudrais utiliser le droit d'auteur. Il n'est pas dans la liste des attributs parallèles à GuidAttribute à http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.aspx – AnneTheAgile

+0

(désolé, ne peut pas modifier mon autre commentaire) C'est super, Je vois System.Reflection.Assembly * a tous les attributs habituels et beaucoup que je n'avais pas connu. http://msdn.microsoft.com/fr-fr/library/system.attribute.aspx Pour utiliser le droit d'auteur, cela a fonctionné; aCopyright = (attribut (AssemblyCopyrightAttribute)) .Copyright.ToString(); – AnneTheAgile

12

J'ai créé cette méthode d'extension qui utilise 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(); 
} 

et vous pouvez facilement l'utiliser comme ça:

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

Une excellente méthode utilitaire. Un indice rapide pour ceux qui souhaitent obtenir la version d'un assemblage. Utilisez: assembly.GetAssemblyAttribute () (détails: http://stackoverflow.com/questions/1144525/getcustomattribute-returns-null-for-assemblyversionattribute) – xDisruptor

4

D'accord, je suis tenté d'aller grâce à de nombreuses ressources pour trouver une méthode pour extraire les attributs .dll pour un Assembly.LoadFrom(path). Mais malheureusement, je ne pouvais pas trouver de bonne ressource. Et cette question était le meilleur résultat pour la recherche sur c# get assembly attributes (Pour moi au moins) Alors j'ai pensé à partager mon travail.

J'ai écrit après simple programme de console pour récupérer les attributs généraux d'assemblage après de nombreuses heures de lutte. Ici, j'ai fourni le code pour que tout le monde puisse l'utiliser pour d'autres travaux de référence. J'ai utilisé CustomAttributes propriété pour cela.Ne hésitez pas à commenter cette approche

code:

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(); 
     } 
    } 
} 

Exemple de sortie:

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

Je signalerais que la propriété ['CustomAttributes'] (https : //msdn.microsoft.com/en-us/library/system.reflection.assembly.customattributes%28v=vs.110%29.aspx) n'est disponible qu'à partir de .NET 4.5 et plus. Dans .NET 4.0 et versions ultérieures, la méthode ['GetCustomAttributesData()'] (https://msdn.microsoft.com/fr-fr/library/system.reflection.assembly.getcustomattributesdata%28v=vs.100%29.aspx) est disponible en alternative. –

2

J'utilise ceci:

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

pour référence:

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 {{ obtenir retour GetCustomAttribute ( délégué (AssemblyProductIdAttribute a) { a.ProductId retour; } ) ; } } Ici, ' « erreur -> Le nom du type ou espace de noms « AssemblyProductIdAttribute AssemblyProductIdAttribute » n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) – Pritam

+0

Pritam: Vous êtes absent le système d'espace de noms. Reflection (using System.Reflection;), ou vous êtes sur une édition/version de cadre étrange. https://msdn.microsoft.com/en-us/library/system.reflection.assemblyproductattribute(v=vs.110).aspx –

+0

__using System.Reflection__ est inclus dans le code, je peux facilement utiliser d'autres fonctions. Aucun d'entre eux ne donne d'erreur. En outre, Framework est également correct. – Pritam

Questions connexes