C# – Get all loaded assemblies

You can get all of the loaded assemblies with AppDomain.CurrentDomain.GetAssemblies(). Here’s an example of looping over all loaded assemblies and outputting their metadata:

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)

Note: This is outputting an interpolated string to the console.

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.dllCode language: plaintext (plaintext)

I’ll show more examples of how you can use the assembly information.

Get custom assembly 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 assembly 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 assembly 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.0Code 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 to 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)