Skip to content

Directory.Delete(path, recursive: true) fails on directories containing junctions #86249

Open
@andrewhickman

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions