如何解决Remove-Item和 [System.IO.File]::Delete() 删除正在使用的文件
我正在编写一个脚本来清理 Autodesk 安装留下的许多 GB 数据,并且我收到了一个错误,关于某个深埋在仍在使用的文件夹结构中的日志文件。所以,我想得到 $_.exception.GetType().fullname
以便我可以有一个 do/while
循环,只要那是失败就循环。或者更有可能循环直到成功或指定次数的尝试失败。
为此,我在 C 驱动器上创建了一个 RTF 文件,在写字板中打开它并尝试使用此代码来获取异常信息。
$path = 'C:\New folder\New Rich Text Document.rtf'
try {
Remove-Item $path -errorAction Stop
} catch {
Write-Host "$($_.exception.GetType().fullname)"
Write-Host "$($_.exception.message)"
}
最终结果,如果没有 -Force 标志,即使打开文件也会被删除。我认为这真的不应该发生。这只是像微软从不费心用写字板实现文件锁定的愚蠢吗?或者我不明白这种行为有什么好的理由吗?更重要的是,有没有办法触发这个条件,这样我就可以真正编写和测试一些优雅响应的代码?理想情况下不使用 MS Office 等,因为我没有它。操作系统中包含的东西将是理想的。 我找到了使用 PowerShell 执行此操作的 this 方法,因此我可以运行第二个脚本来锁定文件并在释放之前循环一段时间,只要该时间小于我的删除超时时间它会工作。但似乎我应该可以,只需打开文件即可。虽然我现在想到导致问题的文件是一个日志文件,所以它可能是通过更像该链接的机制锁定的,而不是实际上被“打开”。但在我看来,打开的文件应该是可删除的。
此外,如标题所述,我也尝试了 [System.IO.File]::Delete($path)
,令我惊讶的是,它也删除了。越来越好奇。
解决方法
某些应用程序在打开文件时不会像 MS Word 文本文件那样锁定文件。但是写字板没有,因此可以在写字板中打开文件时删除文件..
为了测试文件锁,我使用了一个小辅助函数:
function Test-LockedFile {
param (
[parameter(Mandatory = $true,ValueFromPipeline = $true,ValueFromPipelineByPropertyName = $true)]
[Alias('FullName','FilePath')]
[ValidateScript({Test-Path $_ -PathType Leaf})]
[string]$Path
)
$file = [System.IO.FileInfo]::new($Path)
# old PowerShell versions use:
# $file = New-Object System.IO.FileInfo $Path
try {
$stream = $file.Open([System.IO.FileMode]::OpenOrCreate,[System.IO.FileAccess]::Write,[System.IO.FileShare]::Delete) # in this case for deletion
if ($stream) { $stream.Close() }
return $false
}
catch {
return $true
}
}
现在,如果我在 MS Word 中打开一个文件,并测试该文件
Test-LockedFile 'D:\Test\blah.rtf'
返回 True
当我在写字板中打开同一个文件时,测试结果为 False
。
另一种确定文件是否被锁定的方法,尽管偷偷摸摸的是尝试更改该文件的扩展名(或任何与此相关的文件属性)。如果在锁定应用程序中打开,你不能这样做,但在写字板中打开时,没问题..
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。