How to read assembly attributes
.NetReflectionAssembliesAttributes.Net Problem Overview
In my program, how can I read the properties set in AssemblyInfo.cs:
[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("")]
I'd like to display some of these values to the user of my program, so I'd like to know how to load them from the main program and from komponent assemblies I'm using.
.Net Solutions
Solution 1 - .Net
This is reasonably easy. You have to use reflection. You need an instance of Assembly that represents the assembly with the attributes you want to read. An easy way of getting this is to do:
typeof(MyTypeInAssembly).Assembly
Then you can do this, for example:
object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
AssemblyProductAttribute attribute = null;
if (attributes.Length > 0)
{
attribute = attributes[0] as AssemblyProductAttribute;
}
Referencing attribute.Product
will now give you the value you passed to the attribute in your AssemblyInfo.cs. Of course, if the attribute you look for can occur more than once, you may get multiple instances in the array returned by GetCustomAttributes, but this is not usually an issue for assembly level attributes like the ones you hope to retrieve.
Solution 2 - .Net
I've created this extension method that uses 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();
}
and then you can conveniently use it like that:
var attr = targetAssembly.GetAssemblyAttribute<AssemblyDescriptionAttribute>();
if(attr != null)
Console.WriteLine("{0} Assembly Description:{1}", Environment.NewLine, attr.Description);
Solution 3 - .Net
Ok, perhaps a bit out of date now for the original question but I will present this for future reference anyway.
If you want to do it from inside the assembly itself then use the following :
using System.Runtime.InteropServices;
using System.Reflection;
object[] customAttributes = this.GetType().Assembly.GetCustomAttributes(false);
You can then iterate through all of the custom attributes to find the one(s) you require e.g.
foreach (object attribute in customAttributes)
{
string assemblyGuid = string.Empty;
if (attribute.GetType() == typeof(GuidAttribute))
{
assemblyGuid = ((GuidAttribute) attribute).Value;
break;
}
}
Solution 4 - .Net
Okay, I'm tried to go through many resources to find a method to extract .dll attributes for a Assembly.LoadFrom(path)
. But unfortunately I couldn't find any good resource. And this question was the top most result for searching on c# get assembly attributes
(For me at least) So I thought of sharing my work.
I wrote following simple Console Program to retrieve general assembly attributes after many hours of struggle. Here I have provided the code so anyone can use it for further reference work.
I use CustomAttributes
property for this. Feel free to comment on this approach
Code :
using System;
using System.Reflection;
namespace MetaGetter
{
class Program
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom("Path to assembly");
foreach (CustomAttributeData attributedata in assembly.CustomAttributes)
{
Console.WriteLine(" Name : {0}",attributedata.AttributeType.Name);
foreach (CustomAttributeTypedArgument argumentset in attributedata.ConstructorArguments)
{
Console.WriteLine(" >> Value : {0} \n" ,argumentset.Value);
}
}
Console.ReadKey();
}
}
}
Sample Output :
Name : AssemblyTitleAttribute
>> Value : "My Product"
Solution 5 - .Net
I personally really like the implementation of lance Larsen and his static AssemblyInfo class.
One basically pastes the class in his assembly (I usually use the already existing AssemblyInfo.cs file as it fits naming convention)
The code to paste is:
internal static class AssemblyInfo
{
public static string Company { get { return GetExecutingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
public static string Product { get { return GetExecutingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
public static string Copyright { get { return GetExecutingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
public static string Trademark { get { return GetExecutingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
public static string Title { get { return GetExecutingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
public static string Description { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public static string Configuration { get { return GetExecutingAssemblyAttribute<AssemblyConfigurationAttribute>(a => a.Configuration); } }
public static string FileVersion { get { return GetExecutingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }
public static Version Version { get { return Assembly.GetExecutingAssembly().GetName().Version; } }
public static string VersionFull { get { return Version.ToString(); } }
public static string VersionMajor { get { return Version.Major.ToString(); } }
public static string VersionMinor { get { return Version.Minor.ToString(); } }
public static string VersionBuild { get { return Version.Build.ToString(); } }
public static string VersionRevision { get { return Version.Revision.ToString(); } }
private static string GetExecutingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
{
T attribute = (T)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(T));
return value.Invoke(attribute);
}
}
You add a using System; to the top of the file and you're good to go.
For my applications i use this class to set/get/work with my local users settings using:
internal class ApplicationData
{
DirectoryInfo roamingDataFolder;
DirectoryInfo localDataFolder;
DirectoryInfo appDataFolder;
public ApplicationData()
{
appDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfo.Product,"Data"));
roamingDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),AssemblyInfo.Product));
localDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfo.Product));
if (!roamingDataFolder.Exists)
roamingDataFolder.Create();
if (!localDataFolder.Exists)
localDataFolder.Create();
if (!appDataFolder.Exists)
appDataFolder.Create();
}
/// <summary>
/// Gets the roaming application folder location.
/// </summary>
/// <value>The roaming data directory.</value>
public DirectoryInfo RoamingDataFolder => roamingDataFolder;
/// <summary>
/// Gets the local application folder location.
/// </summary>
/// <value>The local data directory.</value>
public DirectoryInfo LocalDataFolder => localDataFolder;
/// <summary>
/// Gets the local data folder location.
/// </summary>
/// <value>The local data directory.</value>
public DirectoryInfo AppDataFolder => appDataFolder;
}
Have a look at Larsens website (MVP), he has cool stuff to draw Inspiration from.
Solution 6 - .Net
I use this:
public static string Title
{
get
{
return GetCustomAttribute<AssemblyTitleAttribute>(a => a.Title);
}
}
for reference:
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;
}
}
}
}
Solution 7 - .Net
If you know the attribute you are looking for is unique, it is much easier to use this often overlooked static helper method of the Attribute
class:
var attribute = Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute))
This is easier because you don't need to mess around with arrays, or worry about that pesky inherit
parameter. You just get the single attribute value directly, or null
if none exists.
Solution 8 - .Net
This is a great way to retrieve specific attributes in a single line of code. No special class required.
string company = ((AssemblyCompanyAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCompanyAttribute), false)).Company;