55using System . Drawing . Drawing2D ;
66using System . Drawing . Imaging ;
77using System . Drawing . Text ;
8+ using System . IO ;
89using System . Runtime . InteropServices ;
910
1011namespace System . Drawing
@@ -25,24 +26,47 @@ internal unsafe partial class Gdip
2526
2627 private static IntPtr LoadNativeLibrary ( )
2728 {
29+ string libraryName ;
30+
2831 IntPtr lib = IntPtr . Zero ;
2932 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) )
3033 {
31- lib = Interop . Libdl . dlopen ( "libgdiplus.dylib" , Interop . Libdl . RTLD_NOW ) ;
34+ libraryName = "libgdiplus.dylib" ;
35+ lib = Interop . Libdl . dlopen ( libraryName , Interop . Libdl . RTLD_NOW ) ;
3236 }
3337 else
3438 {
3539 // Various Unix package managers have chosen different names for the "libgdiplus" shared library.
3640 // The mono project, where libgdiplus originated, allowed both of the names below to be used, via
3741 // a global configuration setting. We prefer the "unversioned" shared object name, and fallback to
3842 // the name suffixed with ".0".
39- lib = Interop . Libdl . dlopen ( "libgdiplus.so" , Interop . Libdl . RTLD_NOW ) ;
43+ libraryName = "libgdiplus.so" ;
44+ lib = Interop . Libdl . dlopen ( libraryName , Interop . Libdl . RTLD_NOW ) ;
4045 if ( lib == IntPtr . Zero )
4146 {
4247 lib = Interop . Libdl . dlopen ( "libgdiplus.so.0" , Interop . Libdl . RTLD_NOW ) ;
4348 }
4449 }
4550
51+ // If we couldn't find libgdiplus in the system search path, try to look for libgdiplus in the
52+ // NuGet package folders. This matches the DllImport behavior.
53+ if ( lib == IntPtr . Zero )
54+ {
55+ string [ ] searchDirectories = ( ( string ) AppContext . GetData ( "NATIVE_DLL_SEARCH_DIRECTORIES" ) ) . Split ( ':' ) ;
56+
57+ foreach ( var searchDirectory in searchDirectories )
58+ {
59+ var searchPath = Path . Combine ( searchDirectory , libraryName ) ;
60+
61+ lib = Interop . Libdl . dlopen ( searchPath , Interop . Libdl . RTLD_NOW ) ;
62+
63+ if ( lib != IntPtr . Zero )
64+ {
65+ break ;
66+ }
67+ }
68+ }
69+
4670 // This function may return a null handle. If it does, individual functions loaded from it will throw a DllNotFoundException,
4771 // but not until an attempt is made to actually use the function (rather than load it). This matches how PInvokes behave.
4872 return lib ;
0 commit comments