PowerShell Remove-Item not waiting

后端 未结 4 1657
不知归路
不知归路 2021-01-13 05:20

If have this piece of code

if(Test-Path -Path $OUT) 
{ 
    Remove-Item $OUT -Recurse 
}
New-Item -ItemType directory -Path $OUT

Sometimes

4条回答
  •  不知归路
    2021-01-13 05:53

    Update: Starting with Windows 10 version 1909, (at least) build 18363.657 (I don't know that Windows Server version and build that corresponds to; run winver.exe to check your version and build), the DeleteFile Windows API function now exhibits synchronous behavior, which implicitly solves the problems with PowerShell's Remove-Item and .NET's System.IO.File.Delete / System.IO.Directory.Delete (but, curiously, not with cmd.exe's rd /s).


    Remove-Item -Recurse is unexpectedly asynchronous, ultimately because the Windows API methods for file and directory removal are inherently asynchronous and Remove-Item doesn't account for that.

    This intermittently, unpredictably manifests in one of two ways:

    • Your case: recreating a removed directory immediately after removal can fail, because the removal may not have completed yet by the time re-creation is attempted.

    • More typically: Removing a nonempty directory itself can fail, if removal of a subdirectory or file hasn't completed yet by the time an attempt is made to remove the parent directory - this is demonstrated in the ServerFault answer marsze links to.

    A potential workaround is to reuse an existing directory by emptying it - instead of deleting and recreating it.

    However, emptying the directory with Get-ChildItem $OUT -Recurse | Remove-Item -Recurse is also susceptible to intermittent failures, though likely less often.

    The problem not only affects PowerShell's Remove-Item, but also cmd.exe's rd /s as well as .NET's [System.IO.Directory]::Delete():

    As of Windows PowerShell v5.1 / PowerShell Core 6.2.0-preview.1 / cmd.exe 10.0.17134.407 / .NET Framework 4.7.03056, .NET Core 2.1, neither Remove-Item, nor rd /s, nor [System.IO.Directory]::Delete() work reliably, because they fail to account for the asynchronous behavior of the Windows API file/directory-removal functions:

    • PowerShell Core bug report
    • cmd.exe bug report
    • .NET Core bug report

    For a custom PowerShell function that provides a reliably synchronous workaround, see this answer.

提交回复
热议问题