Skip to content

Commit 852e318

Browse files
authored
Breaking change for single-file apps (#46945)
1 parent 0c3bf89 commit 852e318

File tree

11 files changed

+93
-13
lines changed

11 files changed

+93
-13
lines changed

docs/core/compatibility/10.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
6060

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

6566
## Networking

docs/core/compatibility/cryptography/10.0/x509-publickey-null.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - X509Certificate and PublicKey key parameters can be null"
3-
description: "Learn about the breaking change in .NET 10 Preview 3 where key parameters in X509Certificate and PublicKey can be null."
3+
description: "Learn about the breaking change in .NET 10 where key parameters in X509Certificate and PublicKey can be null."
44
ms.date: 3/13/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/45325
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
title: "Breaking change - Single-file apps no longer look for native libraries in executable directory"
3+
description: "Learn about the breaking change in .NET 10 where single-file apps no longer look for native libraries in the executable directory."
4+
ms.date: 06/25/2025
5+
ms.custom: https://github.com/dotnet/docs/issues/46356
6+
---
7+
8+
# Single-file apps no longer look for native libraries in executable directory
9+
10+
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.
11+
12+
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.
13+
14+
## Version introduced
15+
16+
.NET 10 Preview 6
17+
18+
## Previous behavior
19+
20+
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.
21+
22+
For example, the following P/Invoke looked *in the application directory* for `lib` and loaded it from there if it existed:
23+
24+
```csharp
25+
[DllImport("lib")
26+
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
27+
static extern void Method()
28+
```
29+
30+
## New behavior
31+
32+
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.
33+
34+
```csharp
35+
// Look in System32 on Windows.
36+
// Search the OS on non-Windows.
37+
[DllImport("lib")
38+
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
39+
static extern void Method()
40+
41+
// Look next to the single-file app because assembly directory
42+
// means application directory for single-file apps.
43+
[DllImport("lib")
44+
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
45+
static extern void Method()
46+
47+
// Look next to the single-file app (because assembly
48+
// directory is searched by default), then default OS search.
49+
[DllImport("lib")
50+
static extern void Method()
51+
```
52+
53+
## Type of breaking change
54+
55+
This is a [behavioral change](../../categories.md#behavioral-change).
56+
57+
## Reason for change
58+
59+
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.
60+
61+
## Recommended action
62+
63+
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>.
64+
65+
If the `RPATH` setting is desired in NativeAOT, explicitly add the corresponding [linker arguments](../../../deploying/native-aot/interop.md#linking) to your project.
66+
67+
## Affected APIs
68+
69+
- P/Invokes
70+
- <xref:System.Runtime.InteropServices.NativeLibrary.Load*?displayProperty=fullName>
71+
- <xref:System.Runtime.InteropServices.NativeLibrary.TryLoad*?displayProperty=fullName>
72+
73+
## See also
74+
75+
- [Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory](search-assembly-directory.md)

docs/core/compatibility/interop/10.0/search-assembly-directory.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory"
3-
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."
3+
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."
44
ms.date: 5/9/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/45911
@@ -18,20 +18,18 @@ Starting in .NET 10, if you specify <xref:System.Runtime.InteropServices.DllImpo
1818

1919
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.
2020

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

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

28-
In this case, the runtime would search the assembly directory and then fall back to the OS search paths.
29-
3028
## New behavior
3129

32-
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.
30+
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.
3331

34-
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.
32+
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.
3533

3634
## Type of breaking change
3735

@@ -57,3 +55,7 @@ public static extern void ExampleMethod();
5755
- P/Invokes using <xref:System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute>
5856
- <xref:System.Runtime.InteropServices.NativeLibrary.Load*?displayProperty=fullName>
5957
- <xref:System.Runtime.InteropServices.NativeLibrary.TryLoad*?displayProperty=fullName>
58+
59+
## See also
60+
61+
- [Single-file apps no longer look for native libraries in executable directory](native-library-search.md)

docs/core/compatibility/networking/10.0/default-http-streaming.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - Streaming HTTP responses enabled by default in browser HTTP clients"
3-
description: "Learn about the breaking change in .NET 10 Preview 3 where streaming HTTP responses are enabled by default in browser HTTP clients."
3+
description: "Learn about the breaking change in .NET 10 where streaming HTTP responses are enabled by default in browser HTTP clients."
44
ms.date: 4/7/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/45644

docs/core/compatibility/sdk/10.0/default-workload-config.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - Change default workload configuration from 'loose manifests' to 'workload sets' mode"
3-
description: "Learn about the breaking change in .NET 10 Preview 2 where the default workload update mode changed."
3+
description: "Learn about the breaking change in .NET 10 where the default workload update mode changed."
44
ms.date: 3/12/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/45000

docs/core/compatibility/sdk/10.0/dotnet-cli-interactive.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - .NET CLI `--interactive` defaults to `true` in user scenarios"
3-
description: "Learn about the breaking change in .NET 10 Preview 3 where the --interactive flag defaults to true in user-centric scenarios."
3+
description: "Learn about the breaking change in .NET 10 where the --interactive flag defaults to true in user-centric scenarios."
44
ms.date: 4/3/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/45548

docs/core/compatibility/sdk/10.0/http-warnings-to-errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - HTTP warnings promoted to errors in dotnet package list and dotnet package search"
3-
description: "Learn about the breaking change in .NET 10 Preview 4 where HTTP warnings are promoted to errors in dotnet package operations."
3+
description: "Learn about the breaking change in .NET 10 where HTTP warnings are promoted to errors in dotnet package operations."
44
ms.date: 5/9/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/45985

docs/core/compatibility/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ items:
5454
href: globalization/10.0/version-override.md
5555
- name: Interop
5656
items:
57+
- name: Single-file apps no longer look for native libraries in executable directory
58+
href: interop/10.0/native-library-search.md
5759
- name: Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory
5860
href: interop/10.0/search-assembly-directory.md
5961
- name: Networking

docs/core/compatibility/windows-forms/10.0/menuitem-contextmenu.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Breaking change - Applications referencing both WPF and WinForms must disambiguate MenuItem and ContextMenu types"
3-
description: "Learn about the breaking change in .NET 10 Preview 1 where applications referencing both WPF and WinForms must disambiguate MenuItem and ContextMenu types."
3+
description: "Learn about the breaking change in .NET 10 where applications referencing both WPF and WinForms must disambiguate MenuItem and ContextMenu types."
44
ms.date: 3/11/2025
55
ai-usage: ai-assisted
66
ms.custom: https://github.com/dotnet/docs/issues/44738

0 commit comments

Comments
 (0)