Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/core/compatibility/10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af

| Title | Type of change | Introduced version |
|-------|-------------------|--------------------|
| [Single-file apps no longer look for native libraries in executable directory](interop/10.0/native-library-search.md) | Behavioral change | Preview 6 |
| [Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory](interop/10.0/search-assembly-directory.md) | Behavioral change | Preview 5 |

## Networking
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - X509Certificate and PublicKey key parameters can be null"
description: "Learn about the breaking change in .NET 10 Preview 3 where key parameters in X509Certificate and PublicKey can be null."
description: "Learn about the breaking change in .NET 10 where key parameters in X509Certificate and PublicKey can be null."
ms.date: 3/13/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/45325
Expand Down
75 changes: 75 additions & 0 deletions docs/core/compatibility/interop/10.0/native-library-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: "Breaking change - Single-file apps no longer look for native libraries in executable directory"
description: "Learn about the breaking change in .NET 10 where single-file apps no longer look for native libraries in the executable directory."
ms.date: 06/25/2025
ms.custom: https://github.com/dotnet/docs/issues/46356
---

# Single-file apps no longer look for native libraries in executable directory

Previously, in [single-file .NET applications](../../../deploying/single-file/overview.md), the directory of the single-file executable was added to the `NATIVE_DLL_SEARCH_DIRECTORIES` property during startup. Consequently, .NET always [probed](../../../dependency-loading/default-probing.md#unmanaged-native-library-probing) the application directory when unmanaged libraries were loaded. On non-Windows with [NativeAOT](../../../deploying/native-aot/index.md), 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 apps, and the `rpath` setting has been removed in NativeAOT. In both cases, <xref:System.Runtime.InteropServices.DllImportSearchPath.AssemblyDirectory?displayProperty=nameWithType> (included in the default behaviour for P/Invokes) means the application directory. If you specify that value or leave the default, .NET looks in the application directory. If you specify flags without that value, .NET no longer looks in the application directory.

## Version introduced

.NET 10 Preview 6

## Previous behavior

Previously, single-file applications always looked in the application directory when loading native libraries. On non-Windows operating systems, NativeAOT applications always looked in the application directory when loading native libraries.

For example, the following P/Invoke looked *in the application directory* for `lib` and loaded it from there if it existed:

```csharp
[DllImport("lib")
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
static extern void Method()
```

## New behavior

Starting in .NET 10, single-file applications only look in the application directory if the search paths for a native library load indicate including the assembly directory.

```csharp
// Look in System32 on Windows.
// Search the OS 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 apps.
[DllImport("lib")
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
static extern void Method()

// Look next to the single-file app (because assembly
// directory is searched by default), then default OS search.
[DllImport("lib")
static extern void Method()
```

## Type of breaking change

This is a [behavioral change](../../categories.md#behavioral-change).

## Reason for change

The existing behavior (always look in the application directory even if search paths exclude it) has caused confusion. It's 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 wasn't previously specified, specify <xref:System.Runtime.InteropServices.DllImportSearchPath.AssemblyDirectory?displayProperty=nameWithType>.

If the `RPATH` setting is desired in NativeAOT, explicitly add the corresponding [linker arguments](../../../deploying/native-aot/interop.md#linking) to your project.

## Affected APIs

- P/Invokes
- <xref:System.Runtime.InteropServices.NativeLibrary.Load*?displayProperty=fullName>
- <xref:System.Runtime.InteropServices.NativeLibrary.TryLoad*?displayProperty=fullName>

## See also

- [Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory](search-assembly-directory.md)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory"
description: "Learn about the breaking change in .NET 10 Preview 5 where specifying DllImportSearchPath.AssemblyDirectory as the only search flag restricts the search to the assembly directory."
description: "Learn about the breaking change in .NET 10 where specifying DllImportSearchPath.AssemblyDirectory as the only search flag restricts the search to the assembly directory."
ms.date: 5/9/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/45911
Expand All @@ -18,20 +18,18 @@ Starting in .NET 10, if you specify <xref:System.Runtime.InteropServices.DllImpo

When <xref:System.Runtime.InteropServices.DllImportSearchPath.AssemblyDirectory?displayProperty=nameWithType> was specified as the only search flag, the runtime searched the assembly directory first. If the library was not found, it fell back to the operating system's default library search behavior.

Example:
For example, with the following code, the runtime would search the assembly directory and then fall back to the OS search paths.

```csharp
[DllImport("example.dll", DllImportSearchPath = DllImportSearchPath.AssemblyDirectory)]
public static extern void ExampleMethod();
```

In this case, the runtime would search the assembly directory and then fall back to the OS search paths.

## New behavior

When <xref:System.Runtime.InteropServices.DllImportSearchPath.AssemblyDirectory?displayProperty=nameWithType> is specified as the only search flag, the runtime searches only in the assembly directory. It does not fall back to the operating system's default library search behavior.
When <xref:System.Runtime.InteropServices.DllImportSearchPath.AssemblyDirectory?displayProperty=nameWithType> is specified as the only search flag, the runtime searches only in the assembly directory. It *doesn't* fall back to the operating system's default library search behavior.

The previous code example would now only search the assembly directory for *example.dll*. If the library is not found there, a <xref:System.DllNotFoundException> will be thrown.
The previous code example now only searches the assembly directory for *example.dll*. If the library is not found there, a <xref:System.DllNotFoundException> is thrown.

## Type of breaking change

Expand All @@ -57,3 +55,7 @@ public static extern void ExampleMethod();
- P/Invokes using <xref:System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute>
- <xref:System.Runtime.InteropServices.NativeLibrary.Load*?displayProperty=fullName>
- <xref:System.Runtime.InteropServices.NativeLibrary.TryLoad*?displayProperty=fullName>

## See also

- [Single-file apps no longer look for native libraries in executable directory](native-library-search.md)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - Streaming HTTP responses enabled by default in browser HTTP clients"
description: "Learn about the breaking change in .NET 10 Preview 3 where streaming HTTP responses are enabled by default in browser HTTP clients."
description: "Learn about the breaking change in .NET 10 where streaming HTTP responses are enabled by default in browser HTTP clients."
ms.date: 4/7/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/45644
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - Change default workload configuration from 'loose manifests' to 'workload sets' mode"
description: "Learn about the breaking change in .NET 10 Preview 2 where the default workload update mode changed."
description: "Learn about the breaking change in .NET 10 where the default workload update mode changed."
ms.date: 3/12/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/45000
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - .NET CLI `--interactive` defaults to `true` in user scenarios"
description: "Learn about the breaking change in .NET 10 Preview 3 where the --interactive flag defaults to true in user-centric scenarios."
description: "Learn about the breaking change in .NET 10 where the --interactive flag defaults to true in user-centric scenarios."
ms.date: 4/3/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/45548
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - HTTP warnings promoted to errors in dotnet package list and dotnet package search"
description: "Learn about the breaking change in .NET 10 Preview 4 where HTTP warnings are promoted to errors in dotnet package operations."
description: "Learn about the breaking change in .NET 10 where HTTP warnings are promoted to errors in dotnet package operations."
ms.date: 5/9/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/45985
Expand Down
2 changes: 2 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ items:
href: globalization/10.0/version-override.md
- name: Interop
items:
- name: Single-file apps no longer look for native libraries in executable directory
href: interop/10.0/native-library-search.md
- name: Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory
href: interop/10.0/search-assembly-directory.md
- name: Networking
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - Applications referencing both WPF and WinForms must disambiguate MenuItem and ContextMenu types"
description: "Learn about the breaking change in .NET 10 Preview 1 where applications referencing both WPF and WinForms must disambiguate MenuItem and ContextMenu types."
description: "Learn about the breaking change in .NET 10 where applications referencing both WPF and WinForms must disambiguate MenuItem and ContextMenu types."
ms.date: 3/11/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/44738
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Breaking change - Incorrect usage of DynamicResource causes application crash"
description: "Learn about the breaking change in .NET 10 Preview 4 where incorrect usage of DynamicResource now causes application crashes."
description: "Learn about the breaking change in .NET 10 where incorrect usage of DynamicResource now causes application crashes."
ms.date: 5/12/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/46089
Expand Down