Powershell - 嵌套循环似乎忽略 if 语句

问题描述 投票:0回答:1

我有一种感觉,这可能是一个相当简单的问题。基本上,我有一个应用程序,在运行时执行期间生成临时 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 )

如有任何建议,我们将不胜感激。

powershell event-handling filesystemwatcher
1个回答
1
投票

我建议您在源目录中创建新文件时使用

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
}
© www.soinside.com 2019 - 2024. All rights reserved.