Directory.Delete(path, recursive: true) fails on directories containing junctions #86249
Description
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:
New-Item -Type Directory 'parent'
New-Item -Type Directory 'target'
New-Item -Type Junction 'parent/link' -Target (Resolve-Path 'target')
try {
[System.IO.Directory]::Delete((Resolve-Path "parent"), $true)
}
catch {
$_.Exception.ToString() | Write-Host
}
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
Activity