【问题标题】:Delete/clear opened text file which is used by another process删除/清除被另一个进程使用的打开的文本文件
【发布时间】:2017-10-17 17:18:17
【问题描述】:

我收到以下异常:

该进程无法访问该文件,因为它正被另一个进程使用

我想简单地清除通过 PowerShell 打开的日志文件。如下:

$path = ...
Clear-Content $path -Force

即使文件已打开,我该怎么做? Windows 编辑器Notepad++ 可以在我的日志查看器打开文件时执行此操作,但我无法在 PowerShell 中执行此操作。编辑如何做到这一点?我也可以用 PowerShell 以某种方式实现这一点吗?

我也试过Set-Content清除文件内容,结果一样。

编辑 - 设置

  • 我的程序写入日志文件(始终没有问题,即使打开了日志查看器)
  • 我使用 glogg 作为日志查看器 (http://glogg.bonnefon.org/)
  • 如果打开 glogg,Powershell 脚本会失败
  • 我可以可靠地重现这一点,并且可以看到,Notepad++ 和 Windows 编辑器可以轻松且始终覆盖文件内容(当然,我的应用程序仍然能够写入日志文件),并且 glogg 立即显示新的日志文件内容

编辑 2:ProcMon 数据

案例 1 - Glogg 已打开且 powershell 失败

11:11:12,1441593    powershell.exe  10304   QueryOpen   D:\VW_LOG.txt   SUCCESS CreationTime: 16.10.2014 09:59:18, LastAccessTime: 16.10.2014 10:13:51, LastWriteTime: 13.10.2017 10:22:07, ChangeTime: 13.10.2017 10:22:07, AllocationSize: 28.672, EndOfFile: 26.451, FileAttributes: A
11:11:12,1442828    powershell.exe  10304   CreateFile  D:\VW_LOG.txt   SHARING VIOLATION   Desired Access: Generic Write, Read Attributes, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Open No Recall, Attributes: n/a, ShareMode: Write, AllocationSize: n/a

案例 2 - Glogg 关闭,powershell 成功

11:12:48,9053637    powershell.exe  10304   QueryOpen   D:\VW_LOG.txt   SUCCESS CreationTime: 16.10.2014 09:59:18, LastAccessTime: 16.10.2014 10:13:51, LastWriteTime: 13.10.2017 10:22:07, ChangeTime: 13.10.2017 10:22:07, AllocationSize: 28.672, EndOfFile: 26.451, FileAttributes: A
11:12:48,9055053    powershell.exe  10304   CreateFile  D:\VW_LOG.txt   SUCCESS Desired Access: Generic Write, Read Attributes, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Open No Recall, Attributes: n/a, ShareMode: Write, AllocationSize: n/a, OpenResult: Opened
11:12:48,9055581    powershell.exe  10304   QuerySecurityFile   D:\VW_LOG.txt   SUCCESS Information: Attribute
11:12:48,9055808    powershell.exe  10304   SetAllocationInformationFile    D:\VW_LOG.txt   SUCCESS AllocationSize: 0
11:12:48,9058881    powershell.exe  10304   CloseFile   D:\VW_LOG.txt   SUCCESS 

EDIT 3 - 可行的替代解决方案

我在我的 powershell 脚本中调用以下命令,它可以完美运行:

ExecuteSimpleBatch "clear_file.bat" $path

function ExecuteSimpleBatch($file, $par)
{
    $fileName = Split-Path $file -leaf
    $fileFolder = Split-Path $file -parent

    Start-Process "cmd" -ArgumentList '/c', $file, $par -WorkingDirectory $fileFolder -WindowStyle hidden
}

“clear_file.bat”的内容:

break > %1

【问题讨论】:

  • 你不能。 Windows 编辑器和 Notepad++ 也不能,所以我假设你在某处得出了错误的结论。如果您对 procmon 有点熟悉,您可以让它运行并监控所有文件活动,同时在 Powershell/Notepad++ 中执行您的操作并从中得出结论。
  • 你能从 sysinternals 下载 procmon 并记录(过滤)你的 powershell 尝试吗?
  • 共享冲突肯定是您的问题。你能分享你的日志吗:停止一切。启动 procmon 并过滤 D:\VW_LOG.txt。启动您的应用、glog、notepad++ 和 powershell 并尝试清除文件。
  • 我的建议仍然是使用 procmon 查看其他程序的创建标志。或者,您可以尝试 procexp 来获取访问标志,但这取决于程序是否仍然打开句柄。
  • CreateFile `Creates or opens a file or I/O device。根据传递给函数的标志,您可以获得共享违规。您可以使用各种选项共享 procmon 跟踪吗?也许这样,我们可以解决。

标签: powershell


【解决方案1】:

我终于找到了一个可行的解决方案:

而不是

Clear-Content $path

可以使用

"" | Out-File $path -NoNewline -Encoding ASCII

为什么

似乎Clear-Content 正在创建一个新文件并用它替换旧文件,而Out-File 尝试写入现有文件(因此打开的读取句柄不会影响此)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 2012-07-25
    • 1970-01-01
    • 2012-10-27
    相关资源
    最近更新 更多