.NET TIPS

コンソール・アプリケーションの強制終了時に処理を行うには?[2.0のみ、C#、VB]

デジタルアドバンテージ 遠藤 孝信
2007/05/31

 コンソール・アプリケーション(通常、コマンド・プロンプト内で実行される)は、[Ctrl]+[C]キーにより強制終了することができるが、アプリケーションによっては突然終了されては困る場合がある。アプリケーションの終了時に一時ファイルの削除や、ログの書き出しといった後処理が必要になる場合だ。

 .NET Framework 2.0のConsoleクラス(System名前空間)では、[Ctrl]+[C]キーが押されたときにCancelKeyPressイベントが発生するようになっており、そのイベント・ハンドラにあらかじめメソッドを登録しておくことにより、アプリケーションの強制終了時に後処理を実行させることができる。

CancelKeyPressイベント・ハンドラの記述と登録

 CancelKeyPressイベント・ハンドラとなるメソッドは次のような形式で記述する(具体例は後述のサンプル・プログラムを参照)。

void MyHandler(object sender, ConsoleCancelEventArgs e) {
  // [Ctrl]+[C]キー押下時の処理の記述
}
Sub MyHandler(ByVal sender As Object, ByVal e As ConsoleCancelEventArgs)
  ' [Ctrl]+[C]キー押下時の処理の記述
End Sub
CancelKeyPressイベント・ハンドラの記述(上:C#、下:VB)

 また、CancelKeyPressイベント・ハンドラの登録は次のようにして行う。

Console.CancelKeyPress += new ConsoleCancelEventHandler(MyHandler);
AddHandler Console.CancelKeyPress, AddressOf MyHandler
CancelKeyPressイベント・ハンドラの登録(上:C#、下:VB)

 次に、これらを使用したサンプル・プログラムを示す。

[Ctrl]+[C]キー押下時に処理を行うサンプル・プログラム

 次のサンプル・プログラムは定期的にログの取得を行い、[Ctrl]+[C]キーにより強制終了させられたときに、たまったログをファイルへ書き出すコンソール・アプリケーションの記述例である。

 このプログラムでは、2秒間隔で「2007/05/29 17:00:24 出力」といったメッセージをコンソール画面とログに出力し、[Ctrl]+[C]キーによる強制終了時に、それまでに出力されたログ・メッセージを「20070529.txt」といった名前のファイルに追加保存する。

// ctrlcevent.cs

using System;
using System.IO;
using System.Text;

// 簡単なログ・クラス
public class MyLogger {

  StringBuilder log = new StringBuilder();

  // ログの追加
  public void Add(string line) {
    log.AppendLine(line);
  }

  // ログの保存(ログ・ファイルの名前は「yyyymmdd.txt」の形式)
  public void Save() {
    string file = DateTime.Now.ToString("yyyyMMdd") + ".txt";
    Encoding enc = Encoding.GetEncoding("Shift_JIS");

    // 追加書き込み(文字コードはShift-JISを使用)
    using (StreamWriter sw = new StreamWriter(file, true, enc)) {
      sw.Write(log.ToString());
    }
  }
}

class MyProgram {

  MyLogger logger = new MyLogger();

  MyProgram() {
    // CancelKeyPressイベント・ハンドラの追加
    Console.CancelKeyPress += new ConsoleCancelEventHandler(Ctrl_C_Pressed);
  }

  void Run() {
    while (true) {
      string line = DateTime.Now + " 出力";
      Console.WriteLine(line);
      logger.Add(line); // ログの追加
      System.Threading.Thread.Sleep(2000); // 2秒間待つ
    }
  }

  // [Ctrl]+[C]キーが押されたときに呼び出される
  void Ctrl_C_Pressed(object sender, ConsoleCancelEventArgs e) {
    logger.Save(); // ログの保存
  }

  static void Main() {
    (new MyProgram()).Run();
  }
}

// コンパイル方法:csc ctrlcevent.cs
[Ctrl]+[C]キー押下時に処理を行うC#のサンプル・プログラム(ctrlcevent.cs)

' ctrlcevent.vb

Imports System
Imports System.IO
Imports System.Text

' 簡単なログ・クラス
Public Class MyLogger
  Dim log As New StringBuilder()

  ' ログの追加
  Public Sub Add(ByVal line As String)
    log.AppendLine(line)
  End Sub

  ' ログの保存(ログ・ファイルの名前は「yyyymmdd.txt」の形式)
  Public Sub Save()
    Dim file As String = DateTime.Now.ToString("yyyyMMdd") + ".txt"
    Dim enc As Encoding = Encoding.GetEncoding("Shift_JIS")

  ' 追加書き込み(文字コードはShift-JISを使用)
    Using sw As New StreamWriter(file, True, enc)
      sw.Write(log.ToString())
    End Using
  End Sub
End Class

Class MyProgram
  Dim logger As New MyLogger()

  Sub New()
    ' CancelKeyPressイベント・ハンドラの追加
    AddHandler Console.CancelKeyPress, AddressOf Ctrl_C_Pressed
  End Sub

  Sub Run()
    While True
      Dim line As String = DateTime.Now + " 出力"
      Console.WriteLine(line)
      logger.Add(line) ' ログの追加
      System.Threading.Thread.Sleep(2000) ' 2秒間待つ
    End While
  End Sub

  ' [Ctrl]+[C]キーが押されたときに呼び出される
  Sub Ctrl_C_Pressed(ByVal sender As Object, ByVal e As ConsoleCancelEventArgs)
    logger.Save() ' ログの保存
  End Sub

  Shared Sub Main()
    Dim p As New MyProgram()
    p.Run()
  End Sub
End Class

' コンパイル方法:vbc ctrlcevent.vb
[Ctrl]+[C]キー押下時に処理を行うVBのサンプル・プログラム(ctrlcevent.vb)

 ちなみに、CancelKeyPressイベント・ハンドラ(このサンプル・プログラムではCtrl_C_Pressedメソッド)では、パラメータで渡されたConsoleCancelEventArgsクラス(System名前空間)のオブジェクトのCancelプロパティにtrueを設定することにより、強制終了をキャンセルすることもできる。

 ただし、[Ctrl]+[C]キーによる強制終了というインターフェイスは昔からコンソール・アプリケーションにとっては標準的なものであり、利用者の混乱を避けるためにも、むやみに変えるべきではない。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:コンソール・アプリケーション
使用ライブラリ:Consoleクラス(System名前空間)
使用ライブラリ:ConsoleCancelEventArgsクラス(System名前空間)

この記事と関連性の高い別の.NET TIPS
コンソール・アプリケーションで[閉じる]ボタンを無効にするには?
コンソール・アプリケーションの強制終了時に処理を行うには?(Win32編)
コンソール・アプリケーションで終了コードを返すには?
コンソール・アプリケーションを途中で終了するには?
ほかのアプリを実行して終了コードを得るには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間