C# – Get list of assemblies currently loaded and output metadata

You can get all of the loaded assemblies and output their metadata like this:

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var name = assembly.GetName(); Console.WriteLine($"Name={name.Name} Version={name.Version} Location={assembly.Location}"); Console.WriteLine(); }
Code language: C# (cs)

This outputs the following information:

Name=System.Private.CoreLib Version=4.0.0.0 Location=C:\Program Files\dotnet\shared\Microsoft.NETCore.App.1.10\System.Private.CoreLib.dll Name=MakolyteLib Version=1.0.0.0 Location=D:\Projects\MakolyteLib\bin\Debug\netcoreapp3.1\MakolyteLib.dll Name=System.Runtime Version=4.2.2.0 Location=C:\Program Files\dotnet\shared\Microsoft.NETCore.App.1.10\System.Runtime.dll Name=System.Runtime.Extensions Version=4.2.2.0 Location=C:\Program Files\dotnet\shared\Microsoft.NETCore.App.1.10\System.Runtime.Extensions.dll Name=System.Console Version=4.1.2.0 Location=C:\Program Files\dotnet\shared\Microsoft.NETCore.App.1.10\System.Console.dll
Code language: plaintext (plaintext)

In the rest of this article, I’ll show how to get custom attributes (such as which build config was used – Debug or Release), how to add your own custom metadata, how to check if it’s a system assembly, and then I’ll show a full example of outputting assembly metadata as JSON.

Get custom attributes

Assembly attributes are defined like this:

[assembly: AssemblyVersion("1.0.0.0")]
Code language: C# (cs)

There are a few attributes that are properties of the assembly class (like name, version, and location), but others are only attainable through the assembly’s custom attributes list. You can get all custom attributes or just get specific ones, as I’ll show below.

Get all custom attributes

You can call assembly.GetCustomAttributesData() to get all custom attribute values, like this:

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { Console.WriteLine(assembly.FullName); foreach (var attribute in assembly.GetCustomAttributesData()) { Console.WriteLine(attribute); } Console.WriteLine(); }
Code language: C# (cs)

This outputs all of the custom attributes for the assembly.

Note: For brevity, I’m only showing the output for MakolyteLib.

MakolyteLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null [System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)] [System.Runtime.CompilerServices.RuntimeCompatibilityAttribute(WrapNonExceptionThrows = True)] [System.Diagnostics.DebuggableAttribute((System.Diagnostics.DebuggableAttribute+DebuggingModes)263)] [System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.1", FrameworkDisplayName = "")] [System.Reflection.AssemblyCompanyAttribute("MakolyteLib")] [System.Reflection.AssemblyConfigurationAttribute("Debug")] [System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] [System.Reflection.AssemblyProductAttribute("MakolyteLib")] [System.Reflection.AssemblyTitleAttribute("MakolyteLib")]
Code language: plaintext (plaintext)

Get a specific custom attribute

You can call assembly.GetCustomAttribute<T> with the attribute type you want to try to get.

using System.Reflection; foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var name = assembly.GetName().Name; var config = assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration; Console.WriteLine($"Name={name} BuildConfig={config}"); Console.WriteLine(); }
Code language: C# (cs)

Note: If the attribute doesn’t exist in the assembly, it’ll return null. That’s why I’m using the null-conditional operator here.

This outputs the following to the console:

Name=System.Private.CoreLib BuildConfig=Release Name=MakolyteLib BuildConfig=Debug Name=System.Runtime BuildConfig= Name=System.Runtime.Extensions BuildConfig= Name=System.Console BuildConfig=
Code language: plaintext (plaintext)

Note: Many system DLLs don’t have the AssemblyConfiguration attribute.

Add your own custom assembly metadata

You can use the AssemblyMetadata attribute to add any custom metadata you want, like this:

using System.Reflection; [assembly: AssemblyMetadata("website", "https://makolyte.com")] [assembly: AssemblyMetadata("favoriteColor", "blue")]
Code language: C# (cs)

To get these attributes, call assembly.GetCustomAttributes<AssemblyMetadataAttribute>() like this:

using System.Reflection; static void Main(string[] args) { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var name = assembly.GetName(); Console.WriteLine($"Name={name.Name} Version={name.Version} Location={assembly.Location}"); var customMetadataList = assembly.GetCustomAttributes<AssemblyMetadataAttribute>() ?? Enumerable.Empty< AssemblyMetadataAttribute>(); foreach (var customMetadata in customMetadataList) { Console.WriteLine($"{customMetadata.Key}={customMetadata.Value}"); } Console.WriteLine(); } }
Code language: C# (cs)

Note: GetCustomAttributes<T>() will return null if there’s no attributes of that type. So always null-check it, or use the null-coalescing operator.

This outputs the custom metadata:

Name=MakolyteLib Version=1.0.0.0 Location=D:\Projects\MakolyteLib\bin\Debug\netcoreapp3.1\MakolyteLib.dll website=https://makolyte.com favoriteColor=blue
Code language: plaintext (plaintext)

Check if it’s a system assembly

What if you want to filter out system assemblies that are loaded as part of .NET?

A simple heuristic is to check if the company name attribute is “Microsoft Corporation”, like this:

using System.Reflection; foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (assembly.GetCustomAttribute<AssemblyCompanyAttribute>().Company != "Microsoft Corporation") { var name = assembly.GetName(); Console.WriteLine($"Name={name.Name} Version={name.Version}"); } }
Code language: C# (cs)

This filtered out system assemblies and only output the name of the assembly I created:

Name=MakolyteLib Version=1.0.0.0
Code language: plaintext (plaintext)

Full example – Getting all loaded assemblies and outputting metadata as JSON

The following gets the assembly name, version, location, if it’s a system assembly, the build configuration, and the target framework name. It then serializes it into JSON and outputs it to the console:

using System.Reflection; using System.Text.Json; using System.Runtime.Versioning; static void Main(string[] args) { var jsonOptions = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true }; foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var metadataJson = JsonSerializer.Serialize(new { assembly.FullName, assembly.GetName().Name, verison = assembly.GetName().Version.ToString(), assembly.Location, isMicrosoftAssembly = assembly.GetCustomAttribute<AssemblyCompanyAttribute>().Company == "Microsoft Corporation", buildConfig = assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration, targetFramework = assembly.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName }, options: jsonOptions); Console.WriteLine(metadataJson); } }
Code language: C# (cs)

This outputs the following JSON to the console:

{ "FullName": "System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", "Name": "System.Private.CoreLib", "verison": "4.0.0.0", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Private.CoreLib.dll", "isMicrosoftAssembly": true, "buildConfig": "Release" } { "FullName": "MakolyteLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Name": "MakolyteLib", "verison": "1.0.0.0", "Location": "D:\\Projects\\MakolyteLib\\bin\\Debug\\netcoreapp3.1\\MakolyteLib.dll", "isMicrosoftAssembly": false, "buildConfig": "Debug", "targetFramework": ".NETCoreApp,Version=v3.1" } { "FullName": "System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "Name": "System.Runtime", "verison": "4.2.2.0", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Runtime.dll", "isMicrosoftAssembly": true } { "FullName": "System.Text.Json, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51", "Name": "System.Text.Json", "verison": "4.0.1.2", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Text.Json.dll", "isMicrosoftAssembly": true } { "FullName": "System.Runtime.Extensions, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "Name": "System.Runtime.Extensions", "verison": "4.2.2.0", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Runtime.Extensions.dll", "isMicrosoftAssembly": true } { "FullName": "System.Console, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "Name": "System.Console", "verison": "4.1.2.0", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Console.dll", "isMicrosoftAssembly": true } { "FullName": "System.Collections.Concurrent, Version=4.0.15.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "Name": "System.Collections.Concurrent", "verison": "4.0.15.0", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Collections.Concurrent.dll", "isMicrosoftAssembly": true } { "FullName": "System.Collections, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "Name": "System.Collections", "verison": "4.1.2.0", "Location": "C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\.1.10\\System.Collections.dll", "isMicrosoftAssembly": true }
Code language: JSON / JSON with Comments (json)

Leave a Comment