diff --git a/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs b/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs
index 64f5aff727fa29..85284922454c94 100644
--- a/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs
+++ b/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs
@@ -130,7 +130,11 @@ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? pa
case Error.ENOTDIR:
return !string.IsNullOrEmpty(path) ?
+#if NET11_0_OR_GREATER
+ new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path), path) :
+#else
new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path)) :
+#endif
new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
case Error.EACCES:
diff --git a/src/libraries/Common/src/System/IO/Win32Marshal.cs b/src/libraries/Common/src/System/IO/Win32Marshal.cs
index bd9e6aab8c2318..28c2b38a925d19 100644
--- a/src/libraries/Common/src/System/IO/Win32Marshal.cs
+++ b/src/libraries/Common/src/System/IO/Win32Marshal.cs
@@ -34,8 +34,13 @@ internal static Exception GetExceptionForWin32Error(int errorCode, string? path
return new FileNotFoundException(
string.IsNullOrEmpty(path) ? SR.IO_FileNotFound : SR.Format(SR.IO_FileNotFound_FileName, path), path);
case Interop.Errors.ERROR_PATH_NOT_FOUND:
+#if NET11_0_OR_GREATER
+ return new DirectoryNotFoundException(
+ string.IsNullOrEmpty(path) ? SR.IO_PathNotFound_NoPathName : SR.Format(SR.IO_PathNotFound_Path, path), path);
+#else
return new DirectoryNotFoundException(
string.IsNullOrEmpty(path) ? SR.IO_PathNotFound_NoPathName : SR.Format(SR.IO_PathNotFound_Path, path));
+#endif
case Interop.Errors.ERROR_ACCESS_DENIED:
return new UnauthorizedAccessException(
string.IsNullOrEmpty(path) ? SR.UnauthorizedAccess_IODenied_NoPathName : SR.Format(SR.UnauthorizedAccess_IODenied_Path, path));
diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs
index ede1b40f391a23..2281871520648e 100644
--- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs
@@ -63,7 +63,11 @@ public PhysicalFileProvider(string root, ExclusionFilters filters)
Root = PathUtils.EnsureTrailingSlash(fullRoot);
if (!Directory.Exists(Root))
{
+#if NET11_0_OR_GREATER
+ throw new DirectoryNotFoundException(null, Root);
+#else
throw new DirectoryNotFoundException(Root);
+#endif
}
_filters = filters;
diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs
index ebcb8ccd40238f..ce6f5d28326626 100644
--- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs
+++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs
@@ -34,7 +34,11 @@ public string TrustedCertificatesDirectory
{
if (!Directory.Exists(value))
{
+#if NET11_0_OR_GREATER
+ throw new DirectoryNotFoundException(SR.Format(SR.DirectoryNotFound, value), value);
+#else
throw new DirectoryNotFoundException(SR.Format(SR.DirectoryNotFound, value));
+#endif
}
SetStringOptionHelper(LdapOption.LDAP_OPT_X_TLS_CACERTDIR, value);
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
index 8ed22d331fcfd2..978eb75cc6048e 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
@@ -67,7 +67,7 @@ public static void CreateFromDirectory(string sourceDirectoryName, Stream destin
if (!Directory.Exists(sourceDirectoryName))
{
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName));
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName);
}
// Rely on Path.GetFullPath for validation of paths
@@ -135,7 +135,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream d
if (!Directory.Exists(sourceDirectoryName))
{
- return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName)));
+ return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName));
}
// Rely on Path.GetFullPath for validation of paths
@@ -190,7 +190,7 @@ public static void CreateFromDirectory(string sourceDirectoryName, string destin
if (!Directory.Exists(sourceDirectoryName))
{
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName));
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName);
}
// Throws if the destination file exists
@@ -253,7 +253,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string d
if (!Directory.Exists(sourceDirectoryName))
{
- return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName)));
+ return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName), sourceDirectoryName));
}
return CreateFromDirectoryInternalAsync(sourceDirectoryName, destinationFileName, includeBaseDirectory, options, cancellationToken);
@@ -309,7 +309,7 @@ public static void ExtractToDirectory(Stream source, string destinationDirectory
if (!Directory.Exists(destinationDirectoryName))
{
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName));
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName);
}
// Rely on Path.GetFullPath for validation of paths
@@ -377,7 +377,7 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire
if (!Directory.Exists(destinationDirectoryName))
{
- return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName)));
+ return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName));
}
// Rely on Path.GetFullPath for validation of paths
@@ -440,7 +440,7 @@ public static void ExtractToDirectory(string sourceFileName, string destinationD
if (!Directory.Exists(destinationDirectoryName))
{
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName));
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName);
}
using FileStream archive = File.OpenRead(sourceFileName);
@@ -509,7 +509,7 @@ public static Task ExtractToDirectoryAsync(string sourceFileName, string destina
if (!Directory.Exists(destinationDirectoryName))
{
- return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName)));
+ return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName));
}
return ExtractToDirectoryInternalAsync(sourceFileName, destinationDirectoryName, options, cancellationToken);
diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs b/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs
index cece82a21343a3..8d62770750f784 100644
--- a/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs
+++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/FileSystemSecurity.cs
@@ -46,7 +46,7 @@ internal FileSystemSecurity(bool isContainer, SafeFileHandle? handle, AccessCont
{
// DirectorySecurity
if ((name != null) && (name.Length != 0))
- exception = new DirectoryNotFoundException(name);
+ exception = new DirectoryNotFoundException(null, name);
else
exception = new DirectoryNotFoundException();
}
diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs
index c787c6939b72f5..04485d30b96dab 100644
--- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs
+++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs
@@ -360,7 +360,7 @@ public void MoveDirectory(string sourceDirectoryName, string destinationDirector
}
catch (DirectoryNotFoundException)
{
- throw new DirectoryNotFoundException(SR.Format(SR.PathNotFound_Path, sourceDirectoryName));
+ throw new DirectoryNotFoundException(SR.Format(SR.PathNotFound_Path, sourceDirectoryName), sourceDirectoryName);
}
catch (PathTooLongException)
{
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs
index da01764dfe8fdd..df737a7564ddd0 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs
@@ -277,7 +277,7 @@ internal SocketError DoOperationSendPackets(Socket socket, SafeSocketHandle _1 /
string? dirname = Path.GetDirectoryName(fnfe.FileName);
if (!string.IsNullOrEmpty(dirname) && !Directory.Exists(dirname))
{
- throw new DirectoryNotFoundException(fnfe.Message);
+ throw new DirectoryNotFoundException(fnfe.Message, dirname);
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
index 26afeaea117eca..571a73528554a5 100644
--- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
+++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
@@ -296,7 +296,7 @@
Decimal constructor requires an array or span of four valid decimal bytes.
- Attempted to access a path that is not on the disk.
+ Unable to find the specified directory.
Attempted to divide by zero.
@@ -2840,6 +2840,12 @@
Could not load the file '{0}'.
+
+ Directory path: '{0}'
+
+
+ Could not find directory '{0}'.
+
File name: '{0}'
diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs b/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs
index ca651ad4c27fc4..5cef1424b6ef9b 100644
--- a/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryNotFoundException.cs
@@ -35,11 +35,59 @@ public DirectoryNotFoundException(string? message, Exception? innerException)
HResult = HResults.COR_E_DIRECTORYNOTFOUND;
}
+ public DirectoryNotFoundException(string? message, string? directoryPath)
+ : this(message, directoryPath, innerException: null)
+ {
+ }
+
+ public DirectoryNotFoundException(string? message, string? directoryPath, Exception? innerException)
+ : base(message ?? (directoryPath is not null
+ ? SR.Format(SR.IO_DirectoryNotFound_Path, directoryPath)
+ : SR.Arg_DirectoryNotFoundException), innerException)
+ {
+ HResult = HResults.COR_E_DIRECTORYNOTFOUND;
+ DirectoryPath = directoryPath;
+ }
+
+ public string? DirectoryPath { get; }
+
+ public override string ToString()
+ {
+ string s = GetType().ToString() + ": " + Message;
+
+ if (!string.IsNullOrEmpty(DirectoryPath))
+ s += Environment.NewLineConst + SR.Format(SR.IO_DirectoryName_Name, DirectoryPath);
+
+ if (InnerException is not null)
+ s += Environment.NewLineConst + InnerExceptionPrefix + InnerException.ToString();
+
+ if (StackTrace is not null)
+ s += Environment.NewLineConst + StackTrace;
+
+ return s;
+ }
+
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[EditorBrowsable(EditorBrowsableState.Never)]
protected DirectoryNotFoundException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
+ foreach (SerializationEntry entry in info)
+ {
+ if (entry.Name == "DirectoryNotFound_DirectoryPath")
+ {
+ DirectoryPath = (string?)entry.Value;
+ break;
+ }
+ }
+ }
+
+ [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("DirectoryNotFound_DirectoryPath", DirectoryPath, typeof(string));
}
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs
index 7c2083cac3d7b3..ed5efa8f8116fb 100644
--- a/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs
@@ -181,8 +181,9 @@ public void MoveTo(string destFileName, bool overwrite)
// as it does on Windows.These checks can be removed if a solution to
// https://github.com/dotnet/runtime/issues/14885 is found that doesn't require
// validity checks before making an API call.
- if (!System.IO.Directory.Exists(Path.GetDirectoryName(FullName)))
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, FullName));
+ string? directoryPath = Path.GetDirectoryName(FullName);
+ if (!System.IO.Directory.Exists(directoryPath))
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, directoryPath), directoryPath);
if (!Exists)
throw new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, FullName), FullName);
diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs
index 059118499d23f3..30a96c843d95c5 100644
--- a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs
@@ -418,7 +418,7 @@ private static void MoveDirectory(string sourceFullPath, string destFullPath, bo
// Throw if the source doesn't exist.
if (Interop.Sys.LStat(srcNoDirectorySeparator, out Interop.Sys.FileStatus sourceFileStatus) < 0)
{
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath));
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath), sourceFullPath);
}
// Source and destination must not be the same file unless it is a case-sensitive rename.
else if (sourceFileStatus.Dev == destFileStatus.Dev &&
@@ -454,7 +454,7 @@ private static void MoveDirectory(string sourceFullPath, string destFullPath, bo
case Interop.Error.EACCES: // match Win32 exception
throw new IOException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, sourceFullPath), errorInfo.RawErrno);
case Interop.Error.ENOENT:
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath));
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath), sourceFullPath);
case Interop.Error.ENOTDIR: // sourceFullPath exists and it's not a directory
throw new IOException(SR.Format(SR.IO_PathNotFound_Path, sourceFullPath));
default:
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index 6bb8a8766c5e88..b8c7dae142fe43 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -10300,6 +10300,13 @@ public DirectoryNotFoundException() { }
protected DirectoryNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
public DirectoryNotFoundException(string? message) { }
public DirectoryNotFoundException(string? message, System.Exception? innerException) { }
+ public DirectoryNotFoundException(string? message, string? directoryPath) { }
+ public DirectoryNotFoundException(string? message, string? directoryPath, System.Exception? innerException) { }
+ public string? DirectoryPath { get { throw null; } }
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
+ public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
+ public override string ToString() { throw null; }
}
public partial class EndOfStreamException : System.IO.IOException
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs
index 400e992503b32c..ad9992153b8411 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IO/DirectoryNotFoundExceptionTests.cs
@@ -3,6 +3,8 @@
using System;
using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
using Xunit;
using System.Tests;
@@ -15,6 +17,7 @@ public static void Ctor_Empty()
{
var exception = new DirectoryNotFoundException();
ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, validateMessage: false);
+ Assert.Null(exception.DirectoryPath);
}
[Fact]
@@ -23,6 +26,7 @@ public static void Ctor_String()
string message = "That page was missing from the directory.";
var exception = new DirectoryNotFoundException(message);
ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message);
+ Assert.Null(exception.DirectoryPath);
}
[Fact]
@@ -32,6 +36,114 @@ public static void Ctor_String_Exception()
var innerException = new Exception("Inner exception");
var exception = new DirectoryNotFoundException(message, innerException);
ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message);
+ Assert.Null(exception.DirectoryPath);
+ }
+
+ [Theory]
+ [InlineData("That directory is gone.", @"C:\missing\dir")]
+ [InlineData("", @"/data/reports")]
+ [InlineData("Custom message", "")]
+ public static void Ctor_String_String(string message, string directoryPath)
+ {
+ var exception = new DirectoryNotFoundException(message, directoryPath);
+ ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message);
+ Assert.Equal(directoryPath, exception.DirectoryPath);
+ }
+
+ [Theory]
+ [InlineData("That directory is gone.", @"C:\missing\dir")]
+ [InlineData("", @"/data/reports")]
+ [InlineData("Custom message", "")]
+ public static void Ctor_String_String_Exception(string message, string directoryPath)
+ {
+ var innerException = new Exception("Inner exception");
+ var exception = new DirectoryNotFoundException(message, directoryPath, innerException);
+ ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message);
+ Assert.Equal(directoryPath, exception.DirectoryPath);
+ }
+
+ [Fact]
+ public static void Ctor_NullDirectoryPath()
+ {
+ string message = "msg";
+ var exception = new DirectoryNotFoundException(message, (string?)null);
+ ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message);
+ Assert.Null(exception.DirectoryPath);
+
+ var innerException = new Exception();
+ var exception2 = new DirectoryNotFoundException(message, (string?)null, innerException);
+ ExceptionHelpers.ValidateExceptionProperties(exception2, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message);
+ Assert.Null(exception2.DirectoryPath);
+ }
+
+ [Fact]
+ public static void Ctor_NullMessageAndNullDirectoryPath()
+ {
+ var exception = new DirectoryNotFoundException(null, (string?)null);
+ ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, validateMessage: false);
+ Assert.Null(exception.DirectoryPath);
+ Assert.NotNull(exception.Message);
+ Assert.NotEmpty(exception.Message);
+ }
+
+ [Fact]
+ public static void Message_AutoConstructed_WhenNullMessage_WithDirectoryPath()
+ {
+ string directoryPath = @"/data/reports";
+ var exception = new DirectoryNotFoundException(null, directoryPath);
+ Assert.NotNull(exception.Message);
+ Assert.Contains(directoryPath, exception.Message);
+ }
+
+ [Fact]
+ public static void ToString_WithDirectoryPath()
+ {
+ string message = "That directory is gone.";
+ string directoryPath = @"C:\missing\dir";
+ var innerException = new Exception("Inner exception");
+ var exception = new DirectoryNotFoundException(message, directoryPath, innerException);
+
+ string toString = exception.ToString();
+ Assert.Contains(": " + message, toString);
+ Assert.Contains(": '" + directoryPath + "'", toString);
+ Assert.Contains("---> " + innerException.ToString(), toString);
+
+ try { throw exception; }
+ catch
+ {
+ Assert.False(string.IsNullOrEmpty(exception.StackTrace));
+ Assert.Contains(exception.StackTrace, exception.ToString());
+ }
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ public static void ToString_WithoutDirectoryPath_OmitsDirectoryLine(string? directoryPath)
+ {
+ var exception = new DirectoryNotFoundException("message", directoryPath);
+ string toString = exception.ToString();
+ Assert.DoesNotContain("Directory path:", toString);
+ }
+
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))]
+ public static void GetObjectData_Roundtrip()
+ {
+ string message = "dir not found";
+ string directoryPath = @"C:\missing\dir";
+ var original = new DirectoryNotFoundException(message, directoryPath);
+
+#pragma warning disable SYSLIB0011
+ var formatter = new BinaryFormatter();
+ using var stream = new MemoryStream();
+ formatter.Serialize(stream, original);
+ stream.Position = 0;
+ var deserialized = (DirectoryNotFoundException)formatter.Deserialize(stream);
+#pragma warning restore SYSLIB0011
+
+ Assert.Equal(message, deserialized.Message);
+ Assert.Equal(directoryPath, deserialized.DirectoryPath);
+ Assert.Equal(original.HResult, deserialized.HResult);
}
}
}
diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs
index c7aeffb6c965d5..5ebdbc325cdd73 100644
--- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs
+++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/NativeObjectSecurity.cs
@@ -150,7 +150,7 @@ private static CommonSecurityDescriptor CreateInternal(ResourceType resourceType
exception = isContainer switch
{
false => new FileNotFoundException(name),
- true => new DirectoryNotFoundException(name)
+ true => new DirectoryNotFoundException(null, name)
};
}
else if (error == Interop.Errors.ERROR_NO_SECURITY_ON_OBJECT)