2009-07-30
現在深夜2時30分なのですが、こんな時間まで何をがんばっていたのかと言うと、PowerShellがCtrl-Cでとめられたりとか、killされたりとか、OSがシャットダウンするとか、そういったようなシグナルを受け取って、終了処理をさせるようにする方法を調べていました。
でも、結局できなそう・・・?(涙
4つくらい方向性は見えたのですが・・・。
一つ目はこんな感じで、Win32APIのSetConsoleCtrlHandlerを呼ぶ方法。
function New-PType() {
[AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object Reflection.AssemblyName 'PInvokeAssembly'), 'Run').DefineDynamicModule('PInvokeModule').DefineType('PInvokeType', "Public,BeforeFieldInit")
}
Win32APIを呼ぶ部分は以下のサイトのものを参考にしました。
この方法がうまく行けばいちばんいいのですが、なぜだかはわからないけど、Ctrl-Cは単純に効かなくなり、何もおこならないようになってしまいます。挙動が変化しているからWin32APIは呼べているんだと思うんだけど・・・。原因不明。こまってます。
2つ目の方法はCtrl-Cだけの対応だけど、System.ConsoleのCancelKeyPressイベントにイベントハンドラを登録する方法。これをやると、なにやら例外が発生してPowerShellごと落ちちゃうんですよね・・・。原因不明。
[System.Console]::Add_CancelKeyPress({echo "trap"})
3つ目の方法はpseventingをつかう方法。これもCtrl-Cだけの対応になっちゃうのかな。これはうまく動きそうなんだけど、追加で別のソフトを入れるのが非常に難しい環境なので、選択肢としてどうか・・・。
4つ目の方法としては、これはまだ試していないけれども、PowerShell v2.0のRegister-ObjectEventコマンドレットを使う方法。これが純正だし、いいきがするけど、今からv2.0にしましょうといっても中々難しい状況なので・・・。
久しぶりに本気で困ってしまいました。そもそもの設計思想の問題だとは思うけど・・・。
誰か何かいい案があれば教えてください・・・。