新しいmp4ファイルのディレクトリを監視し、HandBrakeのCLIツールを使用してファイルを変換するスクリプトを作成しています。ディレクトリの変更を監視するロジックは単独で機能しますが、大きなファイルを「監視」ディレクトリにドロップすると、ファイルのコピーが完了する前に新しいファイルが表示されるとすぐに変換が失敗します。Powershellスクリプトを停止してエラー情報を収集できません
私はdo untilループを使ってファイルがロックされているかどうかをチェックしています。ループは、スタンドアロンスクリプトとして動作しますが、ファイルシステムウォッチャーの内部で使用する場合には、このライン上のエラーなしに停止するスクリプト:$ ErrorActionPreference =「SilentlyContinueという」がコメントされている場合
[System.IO.FileStream] $fs = $convertingFile.OpenWrite();
はこれに関係なく発生しますでる。私は、スクリプトがStart-TranscriptまたはOut-Fileを使用して停止している理由を確認するために、ログ出力を収集できませんでした。
この行にヒットしたスクリプトが停止する理由についてのエラー情報をどのように収集するのが最適でしょうか?
ボーナス:なぜこのスクリプトでエラー情報が表示されないのですか?
$ErrorActionPreference = "SilentlyContinue"
function Start-FileSystemWatcher {
[CmdletBinding()]
param(
[Parameter()]
[string]$Path,
[Parameter()]
[ValidateSet('Changed','Created','Deleted','Renamed')]
[string[]]$EventName,
[Parameter()]
[string]$Filter,
[Parameter()]
[System.IO.NotifyFilters]$NotifyFilter,
[Parameter()]
[switch]$Recurse,
[Parameter()]
[scriptblock]$Action
)
#region Build FileSystemWatcher
$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
if (-not $PSBoundParameters.ContainsKey('Path')) {
$Path = $PWD
}
$FileSystemWatcher.Path = $Path
if ($PSBoundParameters.ContainsKey('Filter')) {
$FileSystemWatcher.Filter = $Filter
}
if ($PSBoundParameters.ContainsKey('NotifyFilter')) {
$FileSystemWatcher.NotifyFilter = $NotifyFilter
}
if ($PSBoundParameters.ContainsKey('Recurse')) {
$FileSystemWatcher.IncludeSubdirectories = $True
}
if (-not $PSBoundParameters.ContainsKey('EventName')) {
$EventName = 'Changed','Created','Deleted','Renamed'
}
if (-not $PSBoundParameters.ContainsKey('Action')) {
$Action = {
switch ($Event.SourceEventArgs.ChangeType) {
'Renamed' {
$Object = "{0} was {1} to {2} at {3}" -f $Event.SourceArgs[-1].OldFullPath,
$Event.SourceEventArgs.ChangeType,
$Event.SourceArgs[-1].FullPath,
$Event.TimeGenerated
}
Default {
$Object = "{0} was {1} at {2}" -f $Event.SourceEventArgs.FullPath,
$Event.SourceEventArgs.ChangeType,
$Event.TimeGenerated
}
}
$WriteHostParams = @{
ForegroundColor = 'Green'
BackgroundColor = 'Black'
Object = $Object
}
Write-Host @WriteHostParams
}
}
$ObjectEventParams = @{
InputObject = $FileSystemWatcher
Action = $Action
}
foreach ($Item in $EventName) {
$ObjectEventParams.EventName = $Item
$ObjectEventParams.SourceIdentifier = "File.$($Item)"
Write-Verbose "Starting watcher for Event: $($Item)"
$Null = Register-ObjectEvent @ObjectEventParams
}
}
$FileSystemWatcherParams = @{
Path = 'X:\share\scripts\ps\converter\input'
Recurse = $True
NotifyFilter = 'FileName'
Verbose = $True
Action = {
$Item = Get-Item $Event.SourceEventArgs.FullPath
$WriteHostParams = @{
ForegroundColor = 'Green'
BackgroundColor = 'Black'
}
$inputFile = "${PWD}\input\$($Item.Name)".trim()
$outputFile = "${PWD}\output\$($Item.Name)".trim()
$logFile = "${PWD}\log\$($Item.Name).txt"
$testLogFile = "${PWD}\log\$($Item.Name)(t).txt"
function mp4-Func {
Start-Transcript -path $logFile
Write-Host "New mp4 file detected..."
$convertingFile = New-Object -TypeName System.IO.FileInfo -ArgumentList $inputFile
$locked = 1
do {
[System.IO.FileStream] $fs = $convertingFile.OpenWrite();
if (!$?) {
Write-Host "Can't convert yet, file appears to be loading..."
sleep 2
}
else {
$fs.Dispose()
$locked = 0
}
} until ($locked -eq 0)
Write-Host "File unlocked and ready for conversion."
HandBrake
Stop-Transcript
$WriteHostParams.Object = "Finished converting: $($Item.Name)"
}
function HandBrake {
.\HandBrakeCLI.exe --input "$inputFile" `
--output "$outputFile" `
--format av_mp4 `
--encoder x264 `
--vb 1700 `
--two-pass `
--aencoder copy:aac `
--ab 320 `
--arate 48 `
--mixdown stereo
}
switch -regex ($Item.Extension) {
'\.mp4' { mp4-Func }
}
Write-Host @WriteHostParams
}
}
@('Created') | ForEach-Object {
$FileSystemWatcherParams.EventName = $_
Start-FileSystemWatcher @FileSystemWatcherParams
}
あなたの投稿は本当に明確な質問ではありませんが、暗示のいくつかの並べ替えを持っています。私は答えで刺すようですが、https://stackoverflow.com/help/how-to-askを見てください –
ありがとうございます。私は問題の説明を書き直そうとしましたが、より明確にすべきいくつかの質問を提供しました。 –