【发布时间】: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