我有一种感觉,这可能是一个相当简单的问题。基本上,我有一个应用程序,在运行时执行期间生成临时 xml 文件。这些对于故障排除很有用。然而,正如刚才所说,它们是暂时的。它们在给定路径中最多存在几秒钟,然后被删除。
我正在致力于自动化脚本以供客户使用(而不是向他们解释如何创建快速 forloop 批处理文件)。我目前所坚持的部分如下。它应该做的是检查目录并等待 xml 文件被创建。它会坐下来不断检查,直到文件存在。一旦完成,它就会跳出该循环并运行复制项以将 xml 文件复制到新目录。
我正在努力集成的部分是我希望用户能够通过按键来结束整个脚本。在此示例中,它是左 ctrl 键。理论上,他们应该能够在开始复制过程后随时结束它(就在我展示的示例代码之前,他们会弹出一个窗口,单击“确定”开始复制过程)。
但是,我现在还无法准确地弄清楚如何正确集成它。 “按按钮结束”代码块可以独立工作。但我该如何整合呢?
一、工作块:
$key = [System.Windows.Input.Key]::LeftCtrl
Write-Warning "Press the $key to end the copy process."
do {
$isCtrl = [System.Windows.Input.Keyboard]::IsKeyDown($key)
if ($isCtrl) {
Write-Host "`nYou pressed $key. Stopping the copy process." -ForegroundColor Green; break
}
Write-Host "." -NoNewline
Start-Sleep -Milliseconds 200
} while ($true)
如上所述,上述方法效果很好。然而,下面是我尝试整合它的尝试。这不起作用。一旦 xml 文件存在于目录中(必须发生这种情况才能跳出第一个 do-until 循环,尽管出于测试目的当然可以将其删除),您会看到写入的复制操作(启用详细),但是当您在 Powershell 中启用调试器时,脚本要么仍在复制项上,要么已循环回到它(我不确定)...
cls
#set key variable and write message on how to end process
$key = [System.Windows.Input.Key]::LeftCtrl
Write-Warning "Press the $key key to end the copy process.`n"
#write waiting for file generation
Write-Host "Waiting for temp files to be generated..`n"
#master loop, copying files until we tell it to stop
do {
#search for new files, but loop doing nothing until they exist
do {
$files = Get-ChildItem $temppath | Where-Object {( New-TimeSpan $_.LastWriteTime).Hours -le 24 }
Start-Sleep -Milliseconds 10
} until ( $files -ne $null )
#copy new files to new directory
Copy-Item $files -Destination $destination -Recurse -Verbose -ErrorAction SilentlyContinue
#look for kill-key
$isCtrl = [System.Windows.Input.Keyboard]::IsKeyDown($key)
if ($isCtrl) {
Write-Host "`nYou pressed $key. Stopping the copy process." -ForegroundColor Green; break
}
} while ( $true )
如有任何建议,我们将不胜感激。
FileSystemWatcher
来处理文件的复制,这样您就可以摆脱内部循环。
Add-Type -AssemblyName PresentationCore, WindowsBase
# the directory where the XML files are created
$source = 'path\to\source\directory'
# the directory where to copy the XML files
$destination = 'path\to\destination\folder'
# `*.xml` filters only files with that extension,
# this filter can be changed or removed altogether
$watcher = [System.IO.FileSystemWatcher]::new($source, '*.xml')
$watcher.EnableRaisingEvents = $true
$evt = Register-ObjectEvent -InputObject $watcher -EventName 'Created' -Action {
param($s, [System.IO.FileSystemEventArgs] $e)
# when the `Created` event is raised,
# this handler copies the file to the destination
Copy-Item $e.FullPath -Destination $destination
# and give details of the file to the console
Write-Host "'$($e.Name)' was copied to '$destination'"
}
$key = [System.Windows.Input.Key]::LeftCtrl
Write-Warning "Press the $key key to end the copy process.`n"
#write waiting for file generation
Write-Host "Waiting for temp files to be generated..`n"
try {
while (-not [System.Windows.Input.Keyboard]::IsKeyDown($key)) {
Start-Sleep -Milliseconds 200
}
}
finally {
Unregister-Event -SourceIdentifier $evt.Name
}