今回は、以下のように C# の try - catch - finally に近い書き方ができます。
try {
# 処理
} catch ([例外の型]) {
param($ex)
# 例外処理
} finally {
# 後処理
}
各ブロックの開始の "{" の前と各ブロックの終了の "}" の後ろは、上記のように、改行せずに記述する必要があります。また例外の型は、上記のように、必ず "()" で囲む必要があります。
catch または finally は、省略可能です。例外の型も省略可能です。
# 追記 ( 2007/11/12 )
catch ブロック内では、break ステートメントを使用して例外を再スローすることができます。当然、任意の例外を throw ステートメントでスローすることもできます。
# 追記ここまで
try {
# 処理
} catch {
# 例外処理
}
で、これらを実現するための関数がこちらです。
function global:try
{
$currentArgIndex = 0;
$tryBlock = $args[$currentArgIndex];
$currentArgIndex++;
if ($tryBlock -isnot [System.Management.Automation.ScriptBlock])
{
throw New-Object "ArgumentException" @("try ブロックの指定が不正です。");
}
if ("catch" -eq $args[$currentArgIndex])
{
$currentArgIndex++;
if ($args[$currentArgIndex] -is [Type])
{
$targetExceptionType = $args[$currentArgIndex];
$currentArgIndex++;
}
$catchBlock = $args[$currentArgIndex];
$currentArgIndex++;
if ($catchBlock -isnot [System.Management.Automation.ScriptBlock])
{
throw New-Object "ArgumentException" @("catch ブロックの指定が不正です。");
}
}
if ("finally" -eq $args[$currentArgIndex])
{
$currentArgIndex++;
$finallyBlock = $args[$currentArgIndex];
$currentArgIndex++;
if ($finallyBlock -isnot [System.Management.Automation.ScriptBlock])
{
throw New-Object "ArgumentException" @("finally ブロックの指定が不正です。");;
}
}
if (($() -eq $catchBlock) -and ($() -eq $finallyBlock))
{
throw New-Object "ArgumentException" @("catch ブロックまたは finally ブロックを指定してください。");
}
&{
$requireFinally = ($() -ne $finallyBlock);
&{
&$tryBlock;
trap
{
if ($() -eq $catchBlock)
{
break;
}
$ex = $_.Exception;
if (($() -ne $targetExceptionType) -and (!$targetExceptionType.IsAssignableFrom($ex.GetType())))
{
break;
}
&$catchBlock $ex;
continue;
}
};
if ($requireFinally)
{
$requireFinally = $False;
&$finallyBlock;
}
trap
{
if ($requireFinally)
{
$requireFinally = $False;
&$finallyBlock;
}
break;
}
};
}
以下のスクリプトを実行すると、動作が確認できます。
try {
"try ブロック実行";
throw New-Object "ArgumentException";
"この文は出力されない";
} catch ([ArgumentException]) {
param ($ex)
"{0} がスローされたから catch ブロック実行" -f $ex.GetType().Name;
} finally {
"finally ブロック実行";
}
出力は以下のようになります。
try ブロック実行
ArgumentException がスローされたから catch ブロック実行
finally ブロック実行
【 ダウンロード 】
自作の PowerShell 関数は、以下の記事からまとめてダウンロードできます。
YokoKen.PowerShell.Scripts