Description
Description
Previously, in single-file .NET applications, the directory of the single-file executable was added to the NATIVE_DLL_SEARCH_DIRECTORIES
property during startup. This means that the application directory was always probed when loading unmanaged libraries. On non-Windows with NativeAOT, the rpath was set to the application directory by default, such that it also always looked for native libraries in the application directory.
The application directory is no longer added to NATIVE_DLL_SEARCH_DIRECTORIES
in single-file and the rpath i setting has been removed in NativeAOT. In both cases, DllImportSearchPath.AssemblyDirectory
(included in the default behaviour for p/invokes) means the application directory - specifying that flag or leaving the default will look in the application directory. Specifying flags without that value will no longer look in the application directory.
Issue: dotnet/runtime#114717
PR: dotnet/runtime#115236
Version
.NET 10 Preview 6
Previous behavior
Single-file applications always looked in the application directory when loading native libraries. NativeAOT applications on non-Windows always looked in the application directory when loading native libraries.
This meant that the following p/invoke would actually look in the application directory for lib
and load it from there if it exists:
[DllImport("lib")
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
static extern void Method()
New behavior
Single-file applications only look in the application directory if the search paths for a native library load indicate including the assembly directory.
// Look in System32 on Windows, OS search on non-Windows
[DllImport("lib")
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
static extern void Method()
// Look next to the single-file app because assembly directory means application directory for single-file
[DllImport("lib")
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
static extern void Method()
// Look next to the single-file app (because we search assembly directory by default), then default OS search
[DllImport("lib")
static extern void Method()
Type of breaking change
- Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
- Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
- Behavioral change: Existing binaries might behave differently at run time.
Reason for change
The existing behaviour - always looking in the application directory even if search paths exclude it - has caused confusion in the past. It is also inconsistent with how the search flags are handled in regular (non-single-file, non-NativeAOT) .NET applications.
Recommended action
If the application/assembly directory is desired for a p/invoke or native library load and was not previously specified, specify DllImportSearchPath.AssemblyDirectory
.
If the RPATH setting is desired in NativeAOT, explicitly add the corresponding linker args to your project: https://learn.microsoft.com/dotnet/core/deploying/native-aot/interop#linking
Feature area
Interop
Affected APIs
- P/Invokes
- NativeLibrary.Load
- NativeLibrary.TryLoad
Metadata
Metadata
Assignees
Type
Projects
Status