3
3
using System . Reflection ;
4
4
using Microsoft . Extensions . DependencyModel ;
5
5
6
- #if ! NET451
7
- using System . Diagnostics ;
8
- using System . IO ;
9
- using System . IO . MemoryMappedFiles ;
10
- using System . Text ;
11
- #endif
12
-
13
6
namespace Serilog . Settings . Configuration . Assemblies
14
7
{
15
8
abstract class AssemblyFinder
@@ -23,8 +16,29 @@ protected static bool IsCaseInsensitiveMatch(string text, string textToFind)
23
16
24
17
public static AssemblyFinder Auto ( )
25
18
{
26
- var dependencyContext = GetDependencyContext ( ) ;
27
- return dependencyContext != null ? new DependencyContextAssemblyFinder ( dependencyContext ) : new DllScanningAssemblyFinder ( ) ;
19
+ var entryAssembly = Assembly . GetEntryAssembly ( ) ;
20
+ if ( entryAssembly != null )
21
+ {
22
+ var isBundled = entryAssembly . Location . Length == 0 ;
23
+ if ( isBundled )
24
+ {
25
+ using var depsJsonStream = SingleFileApplication . GetDepsJsonStream ( ) ;
26
+ if ( depsJsonStream != null )
27
+ {
28
+ using var depsJsonReader = new DependencyContextJsonReader ( ) ;
29
+ var dependencyContext = depsJsonReader . Read ( depsJsonStream ) ;
30
+ return new DependencyContextAssemblyFinder ( dependencyContext ) ;
31
+ }
32
+ }
33
+
34
+ var entryAssemblyContext = DependencyContext . Load ( entryAssembly ) ;
35
+ if ( entryAssemblyContext != null )
36
+ {
37
+ return new DependencyContextAssemblyFinder ( entryAssemblyContext ) ;
38
+ }
39
+ }
40
+
41
+ return new DllScanningAssemblyFinder ( ) ;
28
42
}
29
43
30
44
public static AssemblyFinder ForSource ( ConfigurationAssemblySource configurationAssemblySource )
@@ -41,71 +55,5 @@ public static AssemblyFinder ForDependencyContext(DependencyContext dependencyCo
41
55
{
42
56
return new DependencyContextAssemblyFinder ( dependencyContext ) ;
43
57
}
44
-
45
- static DependencyContext GetDependencyContext ( )
46
- {
47
- var isBundled = string . IsNullOrEmpty ( Assembly . GetEntryAssembly ( ) ? . Location ) ;
48
- if ( ! isBundled )
49
- {
50
- return DependencyContext . Default ;
51
- }
52
-
53
- #if ! NET451
54
- try
55
- {
56
- var currentProcessPath = Process . GetCurrentProcess ( ) . MainModule ? . FileName ;
57
- if ( currentProcessPath != null )
58
- {
59
- var currentProcessExeLength = new FileInfo ( currentProcessPath ) . Length ;
60
- using var currentProcessFile = MemoryMappedFile . CreateFromFile ( currentProcessPath , FileMode . Open , null , 0 , MemoryMappedFileAccess . Read ) ;
61
- using var currentProcessView = currentProcessFile . CreateViewAccessor ( 0 , currentProcessExeLength , MemoryMappedFileAccess . Read ) ;
62
- // See https://github.com/dotnet/runtime/blob/v6.0.3/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs#L216
63
- byte [ ] bundleSignature = {
64
- // 32 bytes represent the bundle signature: SHA-256 for ".net core bundle"
65
- 0x8b , 0x12 , 0x02 , 0xb9 , 0x6a , 0x61 , 0x20 , 0x38 , 0x72 , 0x7b , 0x93 , 0x02 , 0x14 , 0xd7 , 0xa0 , 0x32 ,
66
- 0x13 , 0xf5 , 0xb9 , 0xe6 , 0xef , 0xae , 0x33 , 0x18 , 0xee , 0x3b , 0x2d , 0xce , 0x24 , 0xb3 , 0x6a , 0xae
67
- } ;
68
- // Can't use BinaryUtils.SearchInFile(currentProcessPath, bundleSignature) because it calls MemoryMappedFile.CreateFromFile(currentProcessPath)
69
- // without specifying `MemoryMappedFileAccess.Read` which eventually cause an IO exception to be thrown on Windows:
70
- // > System.IO.IOException: The process cannot access the file
71
- // Note: HostWriter.IsBundle(currentProcessPath, out var bundleHeaderOffset) calls BinaryUtils.SearchInFile(currentProcessPath, bundleSignature)
72
- // So the internal SearchInFile that takes a MemoryMappedViewAccessor is used instead
73
- // Using this internal method is a proof of concept, it needs to be properly rewritten and thus the `Microsoft.NET.HostModel` dependency can be removed.
74
- // internal static unsafe int SearchInFile(MemoryMappedViewAccessor accessor, byte[] searchPattern)
75
- const BindingFlags bindingFlags = BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic ;
76
- var parameterTypes = new [ ] { typeof ( MemoryMappedViewAccessor ) , typeof ( byte [ ] ) } ;
77
- var searchInFile = typeof ( Microsoft . NET . HostModel . AppHost . BinaryUtils ) . GetMethod ( "SearchInFile" , bindingFlags , null , parameterTypes , null ) ;
78
- var bundleSignatureIndex = ( int ? ) searchInFile ? . Invoke ( null , new object [ ] { currentProcessView , bundleSignature } ) ?? - 1 ;
79
- if ( bundleSignatureIndex > 0 && bundleSignatureIndex < currentProcessExeLength )
80
- {
81
- var bundleHeaderOffset = currentProcessView . ReadInt64 ( bundleSignatureIndex - 8 ) ;
82
- using var currentProcessStream = currentProcessFile . CreateViewStream ( 0 , currentProcessExeLength , MemoryMappedFileAccess . Read ) ;
83
- using var reader = new BinaryReader ( currentProcessStream , Encoding . UTF8 ) ;
84
- // See https://github.com/dotnet/runtime/blob/v6.0.3/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs#L32-L39
85
- // and https://github.com/dotnet/runtime/blob/v6.0.3/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs#L144-L155
86
- reader . BaseStream . Position = bundleHeaderOffset ;
87
- var majorVersion = reader . ReadUInt32 ( ) ;
88
- _ = reader . ReadUInt32 ( ) ; // minorVersion
89
- _ = reader . ReadInt32 ( ) ; // numEmbeddedFiles
90
- _ = reader . ReadString ( ) ; // bundleId
91
- if ( majorVersion >= 2 )
92
- {
93
- var depsJsonOffset = reader . ReadInt64 ( ) ;
94
- var depsJsonSize = reader . ReadInt64 ( ) ;
95
- using var depsJsonStream = currentProcessFile . CreateViewStream ( depsJsonOffset , depsJsonSize , MemoryMappedFileAccess . Read ) ;
96
- using var depsJsonReader = new DependencyContextJsonReader ( ) ;
97
- return depsJsonReader . Read ( depsJsonStream ) ;
98
- }
99
- }
100
- }
101
- }
102
- catch
103
- {
104
- return null ;
105
- }
106
- #endif
107
-
108
- return null ;
109
- }
110
58
}
111
59
}
0 commit comments