-
Notifications
You must be signed in to change notification settings - Fork 127
/
DllScanningAssemblyFinder.cs
66 lines (58 loc) · 2.16 KB
/
DllScanningAssemblyFinder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System.Reflection;
namespace Serilog.Settings.Configuration.Assemblies;
sealed class DllScanningAssemblyFinder : AssemblyFinder
{
public override bool CanFindAssemblies => GetProbeDirs().SelectMany(e => Directory.GetFiles(e, "*.dll")).Any();
public override IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind)
{
var probeDirs = GetProbeDirs();
var query = from probeDir in probeDirs
where Directory.Exists(probeDir)
from outputAssemblyPath in Directory.GetFiles(probeDir, "*.dll")
let assemblyFileName = Path.GetFileNameWithoutExtension(outputAssemblyPath)
where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)
let assemblyName = TryGetAssemblyNameFrom(outputAssemblyPath)
where assemblyName != null
select assemblyName;
return query.ToList().AsReadOnly();
static AssemblyName TryGetAssemblyNameFrom(string path)
{
try
{
return AssemblyName.GetAssemblyName(path);
}
catch (BadImageFormatException)
{
return null;
}
}
}
static IEnumerable<string> GetProbeDirs()
{
if (!string.IsNullOrEmpty(AppDomain.CurrentDomain.BaseDirectory))
{
yield return AppDomain.CurrentDomain.BaseDirectory;
#if NETFRAMEWORK
var privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
if (!string.IsNullOrEmpty(privateBinPath))
{
foreach (var path in privateBinPath.Split(';'))
{
if (Path.IsPathRooted(path))
{
yield return path;
}
else
{
yield return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
}
}
}
#endif
}
else
{
yield return Path.GetDirectoryName(typeof(AssemblyFinder).Assembly.Location);
}
}
}