|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Microsoft.CodeAnalysis.Host.Mef;
internal static class MefHostServicesHelpers
{
public static ImmutableArray<Assembly> LoadNearbyAssemblies(ImmutableArray<string> assemblyNames)
{
var assemblies = new List<Assembly>(assemblyNames.Length);
foreach (var assemblyName in assemblyNames)
{
var assembly = TryLoadNearbyAssembly(assemblyName);
if (assembly != null)
{
assemblies.Add(assembly);
}
}
return [.. assemblies];
}
private static Assembly? TryLoadNearbyAssembly(string assemblySimpleName)
{
var thisAssemblyName = typeof(MefHostServicesHelpers).GetTypeInfo().Assembly.GetName();
var assemblyShortName = thisAssemblyName.Name;
var assemblyVersion = thisAssemblyName.Version;
var publicKeyToken = thisAssemblyName.GetPublicKeyToken()?.Aggregate(string.Empty, (s, b) => s + b.ToString("x2"));
if (string.IsNullOrEmpty(publicKeyToken))
{
publicKeyToken = "null";
}
var assemblyName = new AssemblyName(string.Format("{0}, Version={1}, Culture=neutral, PublicKeyToken={2}", assemblySimpleName, assemblyVersion, publicKeyToken));
try
{
return Assembly.Load(assemblyName);
}
catch (Exception)
{
return null;
}
}
public static string? TryFindNearbyAssemblyLocation(string assemblySimpleName)
{
// Try to find the assembly location by looking for a filename matching that assembly name
// at the same location as this assembly.
var thisAssemblyName = typeof(MefHostServicesHelpers).GetTypeInfo().Assembly.Location;
var thisAssemblyFolder = Path.GetDirectoryName(thisAssemblyName);
var potentialAssemblyPath = thisAssemblyFolder != null
? Path.Combine(thisAssemblyFolder, assemblySimpleName + ".dll")
: null;
if (File.Exists(potentialAssemblyPath))
return potentialAssemblyPath;
// Otherwise, fall back to loading the assembly to find the file locations
var assembly = TryLoadNearbyAssembly(assemblySimpleName);
return assembly?.Location;
}
}
|