[解決方法]パスを定義したConfigファイルをConvertFrom-StringDataに渡すとエラー
概要
Configファイルから定数データを読み取るロジックを含んでいるPowerShellスクリプトを作成してデバッグした結果、
「 ConvertFrom-StringData: Invalid pattern '"D:\Program Files\Tesseract-OCR\tesseract.exe"' at offset 5. Unrecognized escape sequence \\P.
」
というようなエラーが発生しました。
原因はConfigファイル内にバックスラッシュ(\、U+005C)を含むファイルやフォルダーのパスを定義しており、
そのままConvertFrom-StringData
にデータを渡すと発生してしまうエラーでした。
このエラーに対して調査した内容と対処方法を紹介します。
この記事のターゲット
- 同じ事象 や 類似事象 でお悩みの方
- 詳しい原因を知りたい方
- 対処方法(解決方法)を知りたい方
環境
PS C:\WINDOWS\system32> $PSVersionTable
Name Value
---- -----
PSVersion 7.3.7
PSEdition Core
GitCommitId 7.3.7
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PS C:\WINDOWS\system32>
エラー
Get-Content
とConvertFrom-StringData
の組合せで設定ファイル(setup.ini)を読み込ませようとしましたが、
ConvertFrom-StringData
でエラーが発生となってしまう。
[DBG]: PS D:\PowerShell_ResizeImageTool> Get-Content "Configファイルのフルパス" -Raw -Encoding UTF8 | ConvertFrom-StringData
ConvertFrom-StringData: Invalid pattern '"D:\Program Files\Tesseract-OCR\tesseract.exe"' at offset 5. Unrecognized escape sequence \\P.
[DBG]: PS D:\PowerShell_ResizeImageTool>
💡 英語の直訳
「Invalid pattern」:無効なパターン
「Unrecognized escape sequence」:認識できないエスケープシーケンス
ソースコード
#################################################################################
# 内容 |setup.ini
# 機能 |ResizeImageToolで使用する設定ファイル
#--------------------------------------------------------------------------------
# |-
#################################################################################
# Tesseract-OCRのインストール場所
ocr_exe_path="D:\Program Files\Tesseract-OCR\tesseract.exe" # 💡 値にバックスラッシュあり
# Tesseract-OCRの一時ファイル作成場所
ocr_temp_path="D:\Downlodas" # 💡 値にバックスラッシュあり
# Tesseract-OCRの一時ファイル作成場所
ocr_check_keyword="sapporo,maruko,sapo,maru,001-0013,北海道,札幌"
# 自動実行モードの設定(true:自動実行、false:対話式実行)
auto_mode=false
# 対象フォルダーのパス
input_folder=""
# リサイズ後の画像サイズ(px指定)
resize_width="800"
resize_height=""
# 元画像が指定サイズ以下の場合の拡大有無(true:拡大する、false:拡大しない)
small_image_resize=false
# WebP変換の有無
webp_convert=true
# 自動生成されるアウトプット用のフォルダー名
output_foldername="To-Resize_"
#################################################################################
# 処理名 |RemoveDoubleQuotes
# 機能 |先頭桁と最終桁にあるダブルクォーテーションを削除
#--------------------------------------------------------------------------------
# 戻り値 |String(削除後の文字列)
# 引数 |target_str: 対象文字列
#################################################################################
Function RemoveDoubleQuotes {
Param (
[System.String]$target_str
)
[System.String]$removed_str = $target_str
If ($target_str.Length -ge 2) {
if (($target_str.Substring(0, 1) -eq '"') -and
($target_str.Substring($target_str.Length - 1, 1) -eq '"')) {
# 先頭桁と最終桁のダブルクォーテーション削除
$removed_str = $target_str.Substring(1, $target_str.Length - 2)
}
}
return $removed_str
}
#################################################################################
# 処理名 |メイン処理
# 機能 |同上
#--------------------------------------------------------------------------------
# |-
#################################################################################
# メッセージコードの設定
Add-Type -TypeDefinition @"
public enum MESSAGECODE {
Successful = 0,
Abend,
Info_LoadedSettingfile,
Confirm_ExecutionTool,
Confirm_ResizeImages,
Error_NotCore,
Error_NotSupportedVersion,
Error_NotWindows,
Error_LoadingSettingfile,
Error_NotExistsTargetpath,
Error_EmptyTargetfolder,
Error_ExecutionTool
}
"@
# モジュール内の共通変数を定義
[MESSAGECODE]$result = [MESSAGECODE]::Successful
[System.String]$prompt_message = ''
[System.String]$result_message = ''
[System.String]$append_message = ''
[System.Text.StringBuilder]$sbtemp=New-Object System.Text.StringBuilder
## 設定ファイル読み込み処理
[System.String]$config_fullpath = 'D:\PowerShell_ResizeImageTool\source\powershell\setup.ini'
try {
# 💡 エラーが発生する場所
[System.Collections.Hashtable]$config = Get-Content $config_fullpath -Raw -Encoding UTF8 | ConvertFrom-StringData
# 対象ファイル
[System.String]$CONFIG_OCR_EXE_PATH=RemoveDoubleQuotes($config.ocr_exe_path)
[System.String]$CONFIG_OCR_TEMP_PATH=RemoveDoubleQuotes($config.ocr_temp_path)
[System.String[]]$CONFIG_OCR_CHECK_KEYWORD=(RemoveDoubleQuotes($config.ocr_temp_path)).split(',')
[System.Boolean]$CONFIG_AUTO_MODE=[System.Convert]::ToBoolean((RemoveDoubleQuotes($config.auto_mode)))
[System.String]$CONFIG_INPUT_FOLDER=RemoveDoubleQuotes($config.input_folder)
[System.String]$CONFIG_RESIZE_WIDTH=RemoveDoubleQuotes($config.resize_width)
[System.String]$CONFIG_RESIZE_HEIGHT=RemoveDoubleQuotes($config.resize_height)
[System.Boolean]$CONFIG_SMALL_IMAGE_RESIZE=[System.Convert]::ToBoolean((RemoveDoubleQuotes($config.small_image_resize)))
[System.Boolean]$CONFIG_WEBP_CONVERT=[System.Convert]::ToBoolean((RemoveDoubleQuotes($config.webp_convert)))
[System.String]$CONFIG_OUTPUT_FOLDERNAME=RemoveDoubleQuotes($config.output_foldername)
$sbtemp=New-Object System.Text.StringBuilder
@("`r`n",`
"対象ファイル: [${config_fullpath}]`r`n")|
ForEach-Object{[void]$sbtemp.Append($_)}
$append_message = $sbtemp.ToString()
$prompt_message = RetrieveMessage ([MESSAGECODE]::Info_LoadedSettingfile) $append_message
Write-Host $prompt_message
}
catch {
$result = [MESSAGECODE]::Error_LoadingSettingfile
$sbtemp=New-Object System.Text.StringBuilder
@("`r`n",`
"エラーの詳細: [${config_fullpath}$($_.Exception.Message)]`r`n")|
ForEach-Object{[void]$sbtemp.Append($_)}
$append_message = $sbtemp.ToString()
$result_message = RetrieveMessage ([MESSAGECODE]::Error_LoadingSettingfile) $append_message
}
原因
ConvertFrom-StriingData
では、パスなどに含まれるバックスラッシュ(\、U+005C)の値をそのまま渡すと、
処理できずに「認識できないエスケープシーケンス(Unrecognized escape sequence
)」となりエラーが発生。
対応方法
推奨する対応方法
ConvertFrom-StriingData
に渡す前に \
を \\
に変換し正しいエスケープシーケンスに置き換えるように変更。
変更によりエラーが発生しなくなり期待通りの動きとなった。
-[System.Collections.Hashtable]$config = Get-Content $config_fullpath -Raw -Encoding UTF8 | ConvertFrom-StringData
+[System.Collections.Hashtable]$config = (Get-Content $config_fullpath -Raw -Encoding UTF8).Replace('\','\\') | ConvertFrom-StringData
推奨しない対応方法
他の対応方法としてConfigファイルに定義しているパスそのものを \
から \\
で定義する事で、
Get-Content
と ConvertFrom-StringData
を組み合わせたコマンドは、そのままの状態で動作するが、
Configファイルを編集するツールの利用者の事を考えるとこの方法は良くない(非推奨)。
#################################################################################
# 内容 |setup.ini
# 機能 |ResizeImageToolで使用する設定ファイル
#--------------------------------------------------------------------------------
# |-
#################################################################################
# Tesseract-OCRのインストール場所
-ocr_exe_path="D:\Program Files\Tesseract-OCR\tesseract.exe"
+ocr_exe_path="D:\\Program Files\\Tesseract-OCR\\tesseract.exe"
# Tesseract-OCRの一時ファイル作成場所
-ocr_temp_path="D:\Downlodas"
+ocr_temp_path="D:\\Downlodas"
参考情報
まとめ
- 原因
ConfigファイルをハッシュテーブルにするConvertFrom-StringData
では、パスに含まれるバックスラッシュ(\、U+005C)をそのまま渡すと“無効なパターン”や“認識できないエスケープシーケンス”としてエラーが発生する - 対処方法1
ConvertFrom-StringData
に渡す前に、パスに含まれるバックスラッシュ(\、U+005C)を「\\
」に置換する事で対応可能 - 対処補法2(非推奨)
Configファイルに定義しているパスの区切りを\
から\\
で定義するよう変更
関連記事
Discussion