@@ -23,36 +23,57 @@ public static class GlobalSettings
2323
2424 static GlobalSettings ( )
2525 {
26- nativeLibraryPathAllowed = Platform . IsRunningOnNetFramework ( ) ;
26+ bool netFX = Platform . IsRunningOnNetFramework ( ) ;
27+ bool netCore = Platform . IsRunningOnNetCore ( ) ;
28+
29+ nativeLibraryPathAllowed = netFX || netCore ;
2730
2831 if ( nativeLibraryPathAllowed )
2932 {
30- /* Assembly.CodeBase is not actually a correctly formatted
31- * URI. It's merely prefixed with `file:///` and has its
32- * backslashes flipped. This is superior to EscapedCodeBase,
33- * which does not correctly escape things, and ambiguates a
34- * space (%20) with a literal `%20` in the path. Sigh.
35- */
36- var managedPath = Assembly . GetExecutingAssembly ( ) . CodeBase ;
37- if ( managedPath == null )
38- {
39- managedPath = Assembly . GetExecutingAssembly ( ) . Location ;
40- }
41- else if ( managedPath . StartsWith ( "file:///" ) )
33+ string assemblyDirectory = GetExecutingAssemblyDirectory ( ) ;
34+
35+ if ( netFX )
4236 {
43- managedPath = managedPath . Substring ( 8 ) . Replace ( '/' , '\\ ' ) ;
37+ // For .NET Framework apps the dependencies are deployed to lib/win32/{architecture} directory
38+ nativeLibraryPath = Path . Combine ( assemblyDirectory , "lib" , "win32" ) ;
4439 }
45- else if ( managedPath . StartsWith ( "file://" ) )
40+ else
4641 {
47- managedPath = @"\\" + managedPath . Substring ( 7 ) . Replace ( '/' , '\\ ' ) ;
42+ // .NET Core apps that depend on native libraries load them directly from paths specified
43+ // in .deps.json file of that app and the native library loader just works.
44+ // However, .NET Core doesn't support .deps.json for plugins yet (such as msbuild tasks).
45+ // To address that shortcoming we assume that the plugin deploys the native binaries to runtimes\{rid}\native
46+ // directories and search there.
47+ nativeLibraryPath = Path . Combine ( assemblyDirectory , "runtimes" , Platform . GetNativeLibraryRuntimeId ( ) , "native" ) ;
4848 }
49+ }
4950
50- managedPath = Path . GetDirectoryName ( managedPath ) ;
51+ registeredFilters = new Dictionary < Filter , FilterRegistration > ( ) ;
52+ }
5153
52- nativeLibraryPath = Path . Combine ( managedPath , "lib" , "win32" ) ;
54+ private static string GetExecutingAssemblyDirectory ( )
55+ {
56+ // Assembly.CodeBase is not actually a correctly formatted
57+ // URI. It's merely prefixed with `file:///` and has its
58+ // backslashes flipped. This is superior to EscapedCodeBase,
59+ // which does not correctly escape things, and ambiguates a
60+ // space (%20) with a literal `%20` in the path. Sigh.
61+ var managedPath = Assembly . GetExecutingAssembly ( ) . CodeBase ;
62+ if ( managedPath == null )
63+ {
64+ managedPath = Assembly . GetExecutingAssembly ( ) . Location ;
65+ }
66+ else if ( managedPath . StartsWith ( "file:///" ) )
67+ {
68+ managedPath = managedPath . Substring ( 8 ) . Replace ( '/' , '\\ ' ) ;
69+ }
70+ else if ( managedPath . StartsWith ( "file://" ) )
71+ {
72+ managedPath = @"\\" + managedPath . Substring ( 7 ) . Replace ( '/' , '\\ ' ) ;
5373 }
5474
55- registeredFilters = new Dictionary < Filter , FilterRegistration > ( ) ;
75+ managedPath = Path . GetDirectoryName ( managedPath ) ;
76+ return managedPath ;
5677 }
5778
5879 /// <summary>
@@ -152,17 +173,18 @@ public static LogConfiguration LogConfiguration
152173 }
153174
154175 /// <summary>
155- /// Sets a path for loading native binaries on .NET Framework.
156- /// When specified, native .dll will first be searched in a
157- /// subdirectory of the given path corresponding to the
158- /// architecture ("x86" or "x64") before falling
159- /// back to searching the default load directories
160- /// (<see cref="DllImportSearchPath.AssemblyDirectory"/>,
176+ /// Sets a path for loading native binaries on .NET Framework or .NET Core.
177+ /// When specified, native library will first be searched under the given path.
178+ /// On .NET Framework a subdirectory corresponding to the architecture ("x86" or "x64") is appended,
179+ /// otherwise the native library is expected to be found in the directory as specified.
180+ ///
181+ /// If the library is not found it will be searched in standard search paths:
182+ /// <see cref="DllImportSearchPath.AssemblyDirectory"/>,
161183 /// <see cref="DllImportSearchPath.ApplicationDirectory"/> and
162- /// <see cref="DllImportSearchPath.SafeDirectories"/>) .
184+ /// <see cref="DllImportSearchPath.SafeDirectories"/>.
163185 /// <para>
164186 /// This must be set before any other calls to the library,
165- /// and is not available on other platforms than .NET Framework.
187+ /// and is not available on other platforms than .NET Framework and .NET Core .
166188 /// </para>
167189 /// </summary>
168190 public static string NativeLibraryPath
@@ -171,7 +193,7 @@ public static string NativeLibraryPath
171193 {
172194 if ( ! nativeLibraryPathAllowed )
173195 {
174- throw new LibGit2SharpException ( "Querying the native hint path is only supported on Windows platforms" ) ;
196+ throw new LibGit2SharpException ( "Querying the native hint path is only supported on .NET Framework and .NET Core platforms" ) ;
175197 }
176198
177199 return nativeLibraryPath ;
@@ -181,7 +203,7 @@ public static string NativeLibraryPath
181203 {
182204 if ( ! nativeLibraryPathAllowed )
183205 {
184- throw new LibGit2SharpException ( "Setting the native hint path is only supported on Windows platforms" ) ;
206+ throw new LibGit2SharpException ( "Setting the native hint path is only supported on .NET Framework and .NET Core platforms" ) ;
185207 }
186208
187209 if ( nativeLibraryPathLocked )
@@ -203,7 +225,10 @@ public static string NativeLibraryPath
203225 internal static string GetAndLockNativeLibraryPath ( )
204226 {
205227 nativeLibraryPathLocked = true ;
206- return Path . Combine ( nativeLibraryPath , Platform . ProcessorArchitecture ) ;
228+
229+ return Platform . IsRunningOnNetFramework ( ) ?
230+ Path . Combine ( nativeLibraryPath , Platform . ProcessorArchitecture ) :
231+ nativeLibraryPath ;
207232 }
208233
209234 /// <summary>
0 commit comments