Title: Get assembly information in C#
To set a project's assembly information, open the Project menu, select Properties, click the Application tab, and click the Assembly Information button. When you do, you'll see the Assembly Information dialog shown on the right. Here you can set various assembly attributes such as the program's title, description, and version.
Unfortunately, getting the assembly information from inside the running program isn't easy. For some reason, Visual Studio stores the assembly information as attributes of the assembly instead of as properties, which would be easy to get.
To get an attribute value, you need to call an Assembly object's GetCustomAttributes method, passing it the type of the attribute that you want to get. You then convert the result (if there is one) into the desired attribute type.
To make this easier, I created an AssemblyInfo class.
The class uses attribute types to get attribute information. Those types are defined in three namespaces, so the class begins with the following using directives to make using the namespaces easier.
using System.Reflection;
using System.Runtime.InteropServices;
using System.Resources;
The following code shows how the class declares variables to hold the different pieces of assembly information.
public class AssemblyInfo
{
// The assembly information values.
public string Title = "", Description = "", Company = "",
Product = "", Copyright = "", Trademark = "",
AssemblyVersion = "", FileVersion = "", Guid = "",
NeutralLanguage = "";
public bool IsComVisible = false;
... Code omitted ...
}
The AssemblyInfo class uses the following GetAssemblyAttribute method to get the assembly attributes.
// Return a particular assembly attribute value.
public static T GetAssemblyAttribute<T>(Assembly assembly)
where T : Attribute
{
// Get attributes of this type.
object[] attributes =
assembly.GetCustomAttributes(typeof(T), true);
// If we didn't get anything, return null.
if ((attributes == null) || (attributes.Length == 0))
return null;
// Convert the first attribute value into
// the desired type and return it.
return (T)attributes[0];
}
This method takes as a parameter the type of the attribute that it should get and an Assembly object representing the assembly of interest. It calls the Assembly object's GetCustomAttribute method to get an array of attributes of the given type.
If the result is null or an empty array, the method returns null. Otherwise the method casts the first array entry into the desired type and returns it.
The AssemblyInfo class's constructors use the GetCustomAttribute method to initialize the object's fields. The following code shows the class's two constructors.
// Constructors.
public AssemblyInfo()
: this(Assembly.GetExecutingAssembly())
{
}
public AssemblyInfo(Assembly assembly)
{
// Get values from the assembly.
AssemblyTitleAttribute titleAttr =
GetAssemblyAttribute<AssemblyTitleAttribute>(assembly);
if (titleAttr != null) Title = titleAttr.Title;
AssemblyDescriptionAttribute assemblyAttr =
GetAssemblyAttribute<AssemblyDescriptionAttribute>(assembly);
if (assemblyAttr != null) Description =
assemblyAttr.Description;
AssemblyCompanyAttribute companyAttr =
GetAssemblyAttribute<AssemblyCompanyAttribute>(assembly);
if (companyAttr != null) Company = companyAttr.Company;
AssemblyProductAttribute productAttr =
GetAssemblyAttribute<AssemblyProductAttribute>(assembly);
if (productAttr != null) Product = productAttr.Product;
AssemblyCopyrightAttribute copyrightAttr =
GetAssemblyAttribute<AssemblyCopyrightAttribute>(assembly);
if (copyrightAttr != null) Copyright = copyrightAttr.Copyright;
AssemblyTrademarkAttribute trademarkAttr =
GetAssemblyAttribute<AssemblyTrademarkAttribute>(assembly);
if (trademarkAttr != null) Trademark = trademarkAttr.Trademark;
AssemblyVersion = assembly.GetName().Version.ToString();
AssemblyFileVersionAttribute fileVersionAttr =
GetAssemblyAttribute<AssemblyFileVersionAttribute>(assembly);
if (fileVersionAttr != null) FileVersion =
fileVersionAttr.Version;
GuidAttribute guidAttr = GetAssemblyAttribute<GuidAttribute>(assembly);
if (guidAttr != null) Guid = guidAttr.Value;
NeutralResourcesLanguageAttribute languageAttr =
GetAssemblyAttribute<NeutralResourcesLanguageAttribute>(assembly);
if (languageAttr != null) NeutralLanguage =
languageAttr.CultureName;
ComVisibleAttribute comAttr =
GetAssemblyAttribute<ComVisibleAttribute>(assembly);
if (comAttr != null) IsComVisible = comAttr.Value;
}
The first constructor simply invokes the second constructor. It uses Assembly.GetExecutingAssembly to pass the second constructor an Assembly object representing the currently executing assembly. This is the constructor you will probably use most because it gets assembly information about the executing assembly.
The second constructor takes an Assembly object as a parameter. This will be useful if you want to get assembly information for an assembly other than the one that is currently executing.
For each piece of assembly information, the constructor calls GetAssemblyAttribute to get the attribute information. (These are the attribute classes contained in the namespaces I mentioned earlier.)
If GetAssemblyAttribute returns a non-null result, the constructor saves the result in the appropriate field. If the result is null, the corresponding field's value remains blank.
The one exception to this pattern is the Version information attribute, which the Assembly class returns it through its GetName method. (Wouldn't it be nice if all of the properties were that easy to get?)
The AssemblyInfo class's constructor is long, but it's really not very complicated. It just repeats the same steps a bunch of times.
Using the AssemblyInfo class is easy. The following code shows how the example's main program uses it to display assembly information.
private void Form1_Load(object sender, EventArgs e)
{
// Get the AssemblyInfo class.
AssemblyInfo info = new AssemblyInfo();
// Display the values.
titleTextBox.Text = info.Title;
descriptionTextBox.Text = info.Description;
companyTextBox.Text = info.Company;
productTextBox.Text = info.Product;
copyrightTextBox.Text = info.Copyright;
trademarkTextBox.Text = info.Trademark;
assemblyVersionTextBox.Text = info.AssemblyVersion;
fileVersionTextBox.Text = info.FileVersion;
guidTextBox.Text = info.Guid;
neutralLanguageTextBox.Text = info.NeutralLanguage;
comVisibleTextBox.Text = info.IsComVisible.ToString();
}
This code creates an instance of the AssemblyInfo class. That invokes the first constructor, which in turn invokes the second.
The main program then simply displays each of the assembly information values. The following picture shows the result.
Download the example to experiment with it and to see additional details.
|