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にしましょうといっても中々難しい状況なので・・・。

久しぶりに本気で困ってしまいました。そもそもの設計思想の問題だとは思うけど・・・。

誰か何かいい案があれば教えてください・・・。

コメントを残す