連載

改訂版
プロフェッショナルVB.NETプログラミング

Chapter 15 コンソール・アプリケーション

株式会社ピーデー 川俣 晶
2004/09/23


 本記事は、(株)技術評論社が発行する書籍『VB6プログラマーのための入門 Visual Basic .NET 独習講座』の一部分を許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。
バッチの活用

 複数のコンソール・アプリケーションを組み合わせることで、便利な機能が実現できることは分かったと思うが、いつも同じ長々としたコマンドを打つのでは、便利とはいえない。ヒストリー機能も、コマンド・プロンプトを閉じると内容が消えてしまうので、毎日パソコンを立ち上げたときに同じコマンドを実行したい、などと思うと不便である。

 そのような場合に便利な機能として「バッチ」というものがある。これは、コマンド・プロンプトから入力しているコマンドの内容をテキスト・ファイルに書いておくと、それを指定するだけで実行してくれるというものである。テキスト・ファイルの拡張子は「.bat」としておく。Windowsのバージョンによっては「.cmd」でも受け付ける。

 例えば、以下の内容のテキスト・ファイルを「sample001.bat」というファイル名で作成してみよう。

1: cd /d c:\
2: dir *.txt
3: Q:\aWrite\@it\vbn\019\smpl\Sample001n\bin\Sample001n.exe
4: pause
リスト15-37 「sample001.bat」というファイル名で作成したバッチ・ファイル

 3行目で指定しているのは、VB.NETで作成するコンソール・アプリケーションで作成したサンプル・プログラム(“Hello World!”を出力する)である。完全な絶対パスで書いてあるが、読者が試す場合はこの部分を変更する必要がある。4行目のpauseコマンドは、何かキーが押されるまで待って終了するコマンドである。これを入れておかないと、一瞬で処理を終えてウィンドウが閉じてしまう。さて、このsample001.batファイルを、エクスプローラなどで表示してダブルクリックすると以下のようになる。

●図15-38 「sample001.bat」をエクスプローラなどから実行した結果

 1行目で、カレント・ディレクトリをc:\に変更し、そこでワイルドカード「*.txt」のファイル一覧を表示し、次にサンプル・プログラムを実行して、最後にキー入力待ちとなる。

スケジュールして無人実行

 バッチのようにコマンドを自動的に実行する仕組みがあると、ついつい、より贅沢な願望を抱いてしまう。バッチ・ファイルを実行する手間すらも惜しむ… 何もしなくても勝手に実行を開始してくれる仕組みはないだろうか? それは、Windowsのタスク・スケジューラとして存在している。バッチも一種の実行ファイルなので、タスク・スケジューラで指定すれば、あらかじめ指定したスケジュールでそれを実行してくれるのである。

 そうなると、次に気になるのはバッチの実行結果をユーザーに伝達する方法である。ログ・ファイルを残す、イベントログに記録する、といった方法も考えられるが、ここでは電子メールで通知する方法を試してみよう。

 電子メールで結果を通知するには、電子メールを送信するコンソール・アプリケーションがあると便利である。リスト15-39は、それを記述した例である。電子メール送信を行うサンプル・プログラムは、名前空間とアセンブリの関係ポリモーフィズムにもあるので、詳しい説明はここでは省く。コマンドラインの第1引数に送信者のメールアドレスを、第2引数にあて先電子メールアドレスを、第3引数にSubjectを、標準入力から送信する内容のテキストを入力する。

 なお、これはあくまでサンプルなので、エラー発生時の対応などが不十分である。実用システムで使う場合は、エラー処理などを充実させて使用していただきたい。

 1: Module Module1
 2:
 3:   Sub Main(ByVal CmdArgs() As String)
 4:     If CmdArgs.Length <> 3 Then
 5:       Console.WriteLine("usage: Sample005n from mailto subject")
 6:       Return
 7:     End If
 8:     Dim sb As New System.Text.StringBuilder()
 9:     Do
10:       Dim s As String
11:       s = Console.ReadLine()
12:       If s Is Nothing Then
13:         Exit Do
14:       End If
15:       sb.Append(s)
16:       sb.Append(Chr(13))
17:       sb.Append(Chr(10))
18:     Loop
19:
20:     System.Web.Mail.SmtpMail.Send(CmdArgs(0), CmdArgs(1), CmdArgs(2), sb.ToString())
21:   End Sub
22:
23: End Module
リスト15-39 標準入力から読み取ったファイルを電子メールで送信するサンプル・プログラム「Sample005n」

 それではこれを使って、ドライブCの残り容量を電子メールで報告するバッチを組んでみよう。まず、ディスクの残り容量を知る方法を考えてみる。取りあえず、dirコマンドで表示されることは分かっているので、そこから残り容量の情報を抜き出すことを考えてみよう。

 「バイトの空き領域」という文字列のある行に空き容量のバイト数が表示されているので、findコマンドでその行を抜き出すようにしてみる。それには「dir c:\|find "バイトの空き領域"」とすればよい。さらには、これを上記の電子メール送信プログラムに流し込めばよい。これらをまとめると、以下のような長いコマンドになる。なお、電子メール送信プログラムは完全な絶対パスで記述してあるが、読者が試す際には、自身の環境に合わせて変更する必要がある。また、報告先の電子メールアドレスも、読者自身のアドレスに変更する必要がある。

dir c:\|find "バイトの空き領域"|Q:\aWrite\@it\vbn\019\smpl\Sample005n\bin\
Sample005n.exe hitomi@piedey.co.jp hitomi@piedey.co.jp "Drive C 残り容量レポート"

 この内容を「sample002.bat」のようなファイル名で保存して、まずは実行してみよう。指定した電子メールアドレスに、以下のような内容のメールが届いていれば成功である。

1:          6 個のディレクトリ   9,722,691,584 バイトの空き領域
リスト15-40 上記のコマンドを実行した場合に送信されるメールの例

 “6 個のディレクトリ”という文字列は不要なものなのだが、dirコマンドでは残り容量と同じ行に表示されるので仕方がない。これを取り除くには、ストリーム・エディタ(sed。Windowsには標準で含まれていない)のような、コンソール・アプリケーションを使用しなければならないが、高度な応用の範疇に入るので、本連載では割愛する。

 最後に、タスク・スケジューラに登録しよう。タスクの追加は、[コントロール・パネル]の[タスク]から行うことができる。

●図15-41 タスクとして実行されるファイルのファイル名と、それを実行するときに使用されるアカウント名を指定する
 
●図15-42 例として毎日午前2時に実行されるようにスケジュールする

 この例では、毎日午前2時にこのバッチは実行され、指定されたメールボックスにドライブCの空き容量を報告してくれることになる。ただし、ログオンしていない状態でも実行されることになるので、ログオンしているときにのみ有効な資源(仮想ドライブなど)をバッチから利用しないように注意しよう

プロセスの終了コード

 前項のバッチでは、エラーの発生の有無にかかわらず、そのまま終了する。しかし、それは実用システムではちょっと困った動作である。例えば、電子メールを送信するコンソール・アプリケーションがエラーになったときはファイルで情報を残す、といったバッチは組めないだろうか。

 これを実現するためには、プログラムがプロセスの終了コードを返すようにすればよい。バッチの中で、このコードを調べて動作を変更する機能が用意されているので、コンソール・アプリケーションからは、正常終了時と異常終了時では異なる値を終了コードとするように記述しておけば、条件次第で動作を変えることができる。

 リスト15-43は、終了コードを返すように、スケジュールして無人実行のサンプル・プログラム「Sample005n」を変更したものである。

 1: Module Module1
 2:
 3:   Function Main(ByVal CmdArgs() As String) As Integer
 4:     Try
 5:       If CmdArgs.Length <> 3 Then
 6:         Console.WriteLine("usage: Sample005n from mailto subject")
 7:         Return 4
 8:       End If
 9:       Dim sb As New System.Text.StringBuilder()
10:       Do
11:         Dim s As String
12:         s = Console.ReadLine()
13:         If s Is Nothing Then
14:           Exit Do
15:         End If
16:         sb.Append(s)
17:         sb.Append(Chr(13))
18:         sb.Append(Chr(10))
19:       Loop
20:
21:       System.Web.Mail.SmtpMail.Send(CmdArgs(0), CmdArgs(1), CmdArgs(2), sb.ToString())
22:       Return 0
23:     Catch ex As Exception
24:       Return 2
25:     End Try
26:   End Function
27:
28: End Module
リスト15-43 プログラムの終了時に終了コードを返すようにサンプル・プログラム「Sample005n」を書き換えたサンプル・プログラム「Sample006n」

 変更点のポイントは、3行目がSub Mainではなく、Integer値を返すFunctionに変わっている点である。これにより、このFunctionが返す数値が終了コードとなる。次に4行目にTryステートメントを記述して、23行目のCatchブロックですべての例外を受けている点である。例外を受けた場合は、24行目のReturn 2で“2”という値を返している。そうでなければ、22行目のReturn 0で“0”を返している。正常終了なら終了コードは“0”、異常終了なら終了コードは“2”ということである。

 このコマンドを活用するバッチは、以下のようになる。

1: dir c:\|find "バイトの空き領域" >last_report.txt
2: Q:\aWrite\@it\vbn\019\smpl\Sample006n\bin\Sample006n.exe hitomi@piedey.co.jp hitomi@piedey.co.jp "Drive C 残り容量レポート" <last_report.txt
3: if errorlevel 2 goto error
4: del last_report.txt
5: exit
6: :error
リスト15-44 サンプル・プログラム「Sample006n」を利用するバッチ・ファイルの記述例

 ポイントは3行目のifコマンドである。このコマンドで、直前のコマンドの終了コードの値を調べることができる。ここでは、終了コードが2以上なら後半のコマンド、つまりgoto errorを実行する。goto errorとは、ラベル“error”にジャンプせよということで、終了コードが2以上のときは、errorラベルのある6行目に処理がジャンプする。そうでないときは、4行目以降が実行される。4行目のdelコマンドはファイルの消去、5行目のexitコマンドは、コマンド・プロンプトを閉じる働きがある。

 つまりこのバッチは、電子メールの送信が成功した場合(終了コード0のとき)は、電子メールで送信する内容を含むlast_report.txtファイルを消去してそのまま終了するが、何か異常があったとき(終了コード2以上のとき)は、ファイルを消さないで終了し、ログ・ファイルを残すように記述したものである。

 実用的に使われるプログラムでは、終了コードは2種類だけで終わらせるのではなく、条件によってさまざまな値を返すように作成するとよいだろう。そうすれば、発生した異常な状態の種類によって、バッチの動作を変えることもできるEnd of Article

VB6プログラマーのための入門 Visual Basic .NET 独習講座』

 本記事は、(株)技術評論社が発行する書籍『VB6 プログラマーのための 入門 Visual Basic .NET 独習講座』から
許可を得て転載したものです。

【本連載と書籍の関係について 】
 この書籍は、本フォーラムで連載した「連載 プロフェッショナルVB.NETプログラミング」を大幅に加筆修正し、発行されたものです。技術評論社、および著者である川俣晶氏のご好意により、書籍の内容を本フォーラムの連載記事として掲載させていただけることになりました。

技術評論社の解説ページ

ご注文はこちらから
 

 INDEX
  [連載] 改訂版 プロフェッショナルVB.NETプログラミング
  Chapter 15 コンソール・アプリケーション
    1.コンソール・アプリケーションとは何か?(1)
    2.コンソール・アプリケーションとは何か?(2)
    3.VB.NETで作成するコンソール・アプリケーション/コマンドライン引数
    4.コンソール・アプリケーションと入出力/リダイレクトを活用する/パイプの活用
  5.バッチの活用/スケジュールして無人実行/プロセスの終了コード
 
「改訂版 プロフェッショナルVB.NETプログラミング 」


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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH