@@ -23,6 +23,9 @@ namespace Microsoft.Data.Sqlite
23
23
/// <seealso href="https://docs.microsoft.com/dotnet/standard/data/sqlite/async">Async Limitations</seealso>
24
24
public partial class SqliteConnection : DbConnection
25
25
{
26
+ private static readonly bool UseOldBehavior35715 =
27
+ AppContext . TryGetSwitch ( "Microsoft.EntityFrameworkCore.Issue35715" , out var enabled35715 ) && enabled35715 ;
28
+
26
29
internal const string MainDatabaseName = "main" ;
27
30
28
31
private const int SQLITE_WIN32_DATA_DIRECTORY_TYPE = 1 ;
@@ -48,6 +51,8 @@ public partial class SqliteConnection : DbConnection
48
51
private static readonly StateChangeEventArgs _fromClosedToOpenEventArgs = new StateChangeEventArgs ( ConnectionState . Closed , ConnectionState . Open ) ;
49
52
private static readonly StateChangeEventArgs _fromOpenToClosedEventArgs = new StateChangeEventArgs ( ConnectionState . Open , ConnectionState . Closed ) ;
50
53
54
+ private static string [ ] ? NativeDllSearchDirectories ;
55
+
51
56
static SqliteConnection ( )
52
57
{
53
58
Type . GetType ( "SQLitePCL.Batteries_V2, SQLitePCLRaw.batteries_v2" )
@@ -626,11 +631,82 @@ public virtual void LoadExtension(string file, string? proc = null)
626
631
627
632
private void LoadExtensionCore ( string file , string ? proc )
628
633
{
629
- var rc = sqlite3_load_extension ( Handle , utf8z . FromString ( file ) , utf8z . FromString ( proc ) , out var errmsg ) ;
630
- if ( rc != SQLITE_OK )
634
+ if ( UseOldBehavior35715 )
635
+ {
636
+ var rc = sqlite3_load_extension ( Handle , utf8z . FromString ( file ) , utf8z . FromString ( proc ) , out var errmsg ) ;
637
+ if ( rc != SQLITE_OK )
638
+ {
639
+ throw new SqliteException ( Resources . SqliteNativeError ( rc , errmsg . utf8_to_string ( ) ) , rc , rc ) ;
640
+ }
641
+ }
642
+ else
643
+ {
644
+ SqliteException ? firstException = null ;
645
+ foreach ( var path in GetLoadExtensionPaths ( file ) )
646
+ {
647
+ var rc = sqlite3_load_extension ( Handle , utf8z . FromString ( path ) , utf8z . FromString ( proc ) , out var errmsg ) ;
648
+ if ( rc == SQLITE_OK )
649
+ {
650
+ return ;
651
+ }
652
+
653
+ if ( firstException == null )
654
+ {
655
+ // We store the first exception so that error message looks more obvious if file appears in there
656
+ firstException = new SqliteException ( Resources . SqliteNativeError ( rc , errmsg . utf8_to_string ( ) ) , rc , rc ) ;
657
+ }
658
+ }
659
+
660
+ if ( firstException != null )
661
+ {
662
+ throw firstException ;
663
+ }
664
+ }
665
+ }
666
+
667
+ private static IEnumerable < string > GetLoadExtensionPaths ( string file )
668
+ {
669
+ // we always try original input first
670
+ yield return file ;
671
+
672
+ string ? dirName = Path . GetDirectoryName ( file ) ;
673
+
674
+ // we don't try to guess directories for user, if they pass a path either absolute or relative - they're on their own
675
+ if ( ! string . IsNullOrEmpty ( dirName ) )
631
676
{
632
- throw new SqliteException ( Resources . SqliteNativeError ( rc , errmsg . utf8_to_string ( ) ) , rc , rc ) ;
677
+ yield break ;
633
678
}
679
+
680
+ bool shouldTryAddingLibPrefix = ! file . StartsWith ( "lib" , StringComparison . Ordinal ) && ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ;
681
+
682
+ if ( shouldTryAddingLibPrefix )
683
+ {
684
+ yield return $ "lib{ file } ";
685
+ }
686
+
687
+ NativeDllSearchDirectories ??= GetNativeDllSearchDirectories ( ) ;
688
+
689
+ foreach ( string dir in NativeDllSearchDirectories )
690
+ {
691
+ yield return Path . Combine ( dir , file ) ;
692
+
693
+ if ( shouldTryAddingLibPrefix )
694
+ {
695
+ yield return Path . Combine ( dir , $ "lib{ file } ") ;
696
+ }
697
+ }
698
+ }
699
+
700
+ private static string [ ] GetNativeDllSearchDirectories ( )
701
+ {
702
+ string ? searchDirs = AppContext . GetData ( "NATIVE_DLL_SEARCH_DIRECTORIES" ) as string ;
703
+
704
+ if ( string . IsNullOrEmpty ( searchDirs ) )
705
+ {
706
+ return Array . Empty < string > ( ) ;
707
+ }
708
+
709
+ return searchDirs ! . Split ( new [ ] { Path . PathSeparator } , StringSplitOptions . RemoveEmptyEntries ) ;
634
710
}
635
711
636
712
/// <summary>
0 commit comments