Open andrewhickman opened 1 year ago
Tagging subscribers to this area: @dotnet/area-system-io See info in area-owners.md if you want to be subscribed.
Author: | andrewhickman |
---|---|
Assignees: | - |
Labels: | `area-System.IO`, `untriaged` |
Milestone: | - |
@andrewhickman thanks for the report, any interest in debugging some? Visual Studio should be able to automatically pull sources and symbols down.
I can provide a failing unit test, that fails in both .NET Framework and .NET 8 using CfApi, if thats of any help.
@AliveDevil Any interest in combining that with a fix and offering a PR?
Looked further into this: I'm hitting an issue with Directory.Delete where a folder, which has been customized (i.e. changed folder icon) can't be deleted anymore because the folder has the Read Only attribute. So, unfortunately not directly related to this issue here.
Debugging this issue shows that a call to DeleteVolumeMountPoint
causes the error.
The directory link
to delete with (Directory.Delete(@"C:\Test", true)
is a junction (mklink C:\Test\link C:\Test\sample /J
) not a volume mount point.
FileSystem.cs (.net 8.0)
in private static void RemoveDirectoryRecursive(string fullPath, ref Interop.Kernel32.WIN32_FIND_DATA findData, bool topLevel)
if (findData.dwReserved0 == 2684354563u)
{
string mountPoint = Path.Join(fullPath, stringFromFixedBuffer2, "\\");
if (!Interop.Kernel32.DeleteVolumeMountPoint(mountPoint) && ex == null)
{
lastPInvokeError = Marshal.GetLastPInvokeError();
if (lastPInvokeError != 0 && lastPInvokeError != 3)
{
ex = Win32Marshal.GetExceptionForWin32Error(lastPInvokeError, stringFromFixedBuffer2);
}
}
}
Description
On Windows, when recursively deleting a directory containing a junction,
System.IO.Directory.Delete(String, Boolean)
fails.Symbolic links work as expected.
Reproduction Steps
Since there's no API to create junctions, this is mostly easily reproduced in powershell:
Expected behavior
The parent directory and junction should be removed successfully.
Actual behavior
The junction is removed, but the parent directory is left behind. The exception message depends on whether the script is run as administrator or not:
Non-admin
``` System.Management.Automation.MethodInvocationException: Exception calling "Delete" with "2" argument(s): "Access to the path 'link' is denied." ---> System.UnauthorizedAccessException: Access to the path 'link' is denied. at System.IO.FileSystem.RemoveDirectoryRecursive(String fullPath, WIN32_FIND_DATA& findData, Boolean topLevel) at System.IO.FileSystem.RemoveDirectory(String fullPath, Boolean recursive) at CallSite.Target(Closure , CallSite , Type , Object , Boolean ) --- End of inner exception stack trace --- at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception) at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) ```Admin
``` System.Management.Automation.MethodInvocationException: Exception calling "Delete" with "2" argument(s): "The parameter is incorrect. : 'link'" ---> System.IO.IOException: The parameter is incorrect. : 'link' at System.IO.FileSystem.RemoveDirectoryRecursive(String fullPath, WIN32_FIND_DATA& findData, Boolean topLevel) at System.IO.FileSystem.RemoveDirectory(String fullPath, Boolean recursive) at CallSite.Target(Closure , CallSite , Type , Object , Boolean ) --- End of inner exception stack trace --- at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception) at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) ```Regression?
I'm able to reproduce this using the script in both powershell 5.1.19041.2673 (.NET Framework 4.8.4614.0), and powershell core 7.2.11 (.NET 6.0.16)
Known Workarounds
Since the junction is removed, the operation can simply be retried to workaround the issue.
Configuration
Reproduced on Windows 22H2 (build 19045.2846)
Other information
No response