Windowsバッチが正常に動作しない場合に見直すポイント(文字コード、改行コード)

Windowsのバッチファイルは、特定の文字コードや改行コードを使用しないと正常に動作しません。
具体的には、以下の文字コードや改行コードを用いる必要があります。

・文字コードは「SJIS」を使用する(chcpコマンドで文字コードを変更しない場合)

・改行コードは「CRLF」を使用する


既存のファイルをコピーしてそれをベースにバッチファイルを作成するような時に、文字コードを誤ってしまうことが多いです。
また、FTP(FFFTP)やGitを用いてサーバ間でファイルのやりとりをする時に、意図せずに改行コードが変わってしまうことも多いです。
既存のファイルをコピーしたり、サーバからバッチファイルを落としてきたりする場合には注意する必要があります。

以下では、文字コードや改行コードを誤るとどのように挙動が変わるのかを見ていきます。
文字コードを誤ると、2バイト文字(日本語等)の部分が文字化けします。フォルダ名やファイル名に2バイト文字が含まれていたり、データに2バイト文字が含まれていたりするような場合は、正常に動作しなくなります。
また、改行コードを誤ると、改行が無視されてコマンドが実行されます。通常のバッチファイルでは改行でコマンドを区切るため、コマンドを上手く区切られなくなり、正常に動作しなくなります。

【サンプル】

【文字コード・改行コードが正しい場合の動作】

【文字コードが「UTF-8」の場合の動作】

【改行コードが「LF」の場合の動作】


いかがでしたでしょうか?

今回は、Windowsバッチが正常に動作しない理由として、ありがちな2つの理由を紹介しました。
(現在私が担当している案件でも、Gitの設定の問題でサーバから落としてきたバッチファイルが動かなくなるという問題に出くわしていました。本当によくあることです。)

今回紹介したように、文字コードや改行コードを誤るとHello Wolrdすら正常に動作しなくなるので、簡単なスクリプトすら動作しなくなることをもって原因調査であたりをつけることができます。
正常に動作しない場合は、コメントアウトやexitコマンドを入れて簡単なコードに書き変えてみて原因を探ると良いでしょう。
(ちなみに、Windowsバッチに限らず、この手の誤りはスクリプト言語全般にありがちです)

原因調査に時間を取られる人が一人でも減れば幸いです!

初めてのWindowsバッチ

Windowsバッチを作ったことが無い方向けに、Windowsバッチの用途や使い方を書いた入門的な記事です。
詳しいコマンドの使い方は記載しませんので、必要に応じて調べてみて下さい。

【Windowsバッチとは】

WindowsOSに標準で用意されている実行ファイル形式であり、拡張子は.batである。
エクスプローラ上でダブルクリックすることで、記述されたDOSコマンド(スクリプト)を自動実行することができる。
簡単な制御や実行ファイル呼び出しを記述可能で、要件に合わせて一連の処理を取りまとめたい時に使用される。

【WindowsバッチでHello World(Windowsバッチの導入)】

WindowsOSであることが前提です。

1.エクスプローラを開き、表示 > ファイル名拡張子 のチェックを入れる。

2.任意の名前でテキストドキュメントを新規作成した後、ファイルの名前を変更する。拡張子を「.txt」から「.bat」に変更する。

3.2で作成したファイルを 右クリック > 編集 で選択し、下記のように入力して保存する。

4.3で編集したファイルをダブルクリックする。コンソールが表示され、下記のように表示されればOK。

【Windowsバッチでできること】

Windowsバッチは複雑な処理を記述するには不向きですが、下記で挙げるような処理であれば記述可能です。
実行ファイルを部品として組み合わせる分には困ることは少なく、「WindowsOSであれば初期設定無しで動く」「習得が容易で、エンジニアであればメンテナンスできる人も多い」といった特徴から、気軽に導入することができます。

1.コンソールへの文字列表示(標準出力)

Hello Worldの例の通り、コンソールへの文字列表示が可能です。
“echo “の後に表示させたい文字列を記述することで、その文字列を表示することができます。
なお、Windowsバッチでは実行されるコマンドもコンソールに表示されるのですが、”@echo off”と記述すれば以降はコマンドのコンソール表示を抑止することができます。
また、Windowsバッチは全てのコマンドの実行が完了したら自動的にウインドウを閉じてしまうので、表示内容を確認したい場合は”pause”と記述して一時的に処理を中断(任意のキー押下で再開)する必要があります。

2.外部の実行ファイルの実行

実行ファイルのパスを記述することで、Windowsバッチから外部の実行ファイルを実行することができます。
実行ファイルのパスの後にスペース区切りで文字列を入力すれば、その文字列を引数として与えることもできます。

例えば、下記のように記述すれば、WindowsOS標準のプログラム言語「C#」のコンパイラを起動することができます。

C#のコンパイル済み実行ファイル(.exe)やjavaのコンパイル済み実行ファイル(.jar)があるなら、そのファイルのパスを記述することでその実行ファイルを実行することができます。
下記は、C#の実行ファイル C:\tmp\Program.exe を実行する例です。

また、Windowsバッチよりも強力な機能を持ったWindowsOS標準のスクリプト言語「Windows Power Shell」は、OSの設定によってはダブルクリックで実行できないという難点があるのですが、下記のように記述することで設定問わずダブルクリックで実行できるようになります。
(Windows Power Shell は環境変数でパスが通っているので、実行ファイルのパスの指定は不要です)

ダブルクリックするだけで引数付きで実行ファイルを実行したり、複数の実行ファイルを実行したり、Windows Power Shell のスクリプトを実行したりできるので、単純に外部の実行ファイルの実行したい時にもWindowsバッチのファイルを作る価値があります。
難しい処理はC#やWindows Power Shell等で記述し、実行はバッチファイルから行う、というスタイルがWindowsOSの場合は馴染みやすいと思います。

3.現在のパス(カレントディレクトリ)の変更

Windowsバッチでは、実行直後はWindowsバッチのファイルが存在するパスを指しています。
例えば、C:\tmp\hoge.bat を実行した場合、実行直後のパスは C:\tmp\ となります。
ファイルのパス指定は現在のパスを起点に相対パスで指定することができ、例えば C:\tmp\ にいる場合は、C:\tmp\Program.exe を

と指定して実行することが可能です。
(.\は省略することも可能です)

現在のパス(カレントディレクトリ)を変更したい場合は、cdコマンドで変更することができます。
cdコマンドのパス指定は絶対パスでも相対パスでも可能で、例えば C:\tmp\ から C:\hoge\ に移動したい場合は、

で移動できます。

他の環境でもWindowsバッチを動かしたい場合は、相対パスが便利です。

4.フォルダの作成

Windowsバッチでは、mkdirコマンドでフォルダを作成することができます。フォルダ名には絶対パス・フルパス両方指定可能です。

なお、フォルダを削除することもでき、コマンドはrmdirコマンドです。

5.ファイルの作成

Windowsバッチでは標準出力の内容をファイルに出力することが可能です。
(出力先は絶対パス・フルパス両方指定可能です)

例えば、以下のように記述することで、Hello World! と書かれたテキストが C:\tmp\hoge.txt に出力されます。
(表示の都合上、大なり記号は全角で入力しています。コピペする際はご注意下さい。)

“>”の部分はリダイレクトと呼ばれており、”>”と記述すれば上書きで出力、”>>”と記述すれば改行して追記で出力となります。

なお、空ファイルを出力するには、下記のように記述すれば良いです(空の文字を入力する、という意味です)。

6.変数の利用

Windowsバッチでは変数を利用することが可能です。

以下は、変数を利用してHello World!を出力する例です。SETで変数を定義、%%で囲むことで変数の参照(正確には展開)が可能です。

例えば、実行したWindowsバッチのフルパスの取得や、システム時刻の取得で変数を使う場合が多いです。
実行したWindowsバッチのフルパスの取得は

システム時刻(YYYYMMDDHHMMSS)の取得は

で可能です。

7.IF文の制御

WindowsバッチではIF文で簡単な制御を行うことができます。

例えば、ファイル・フォルダの存在確認は下記のような記述で実現可能です。

ここで、hoge を hoge\ とすることで、フォルダのみの存在確認が可能になります。
hoge という名前のファイルが存在していても偽とすることができます。
また、”IF”の直後に”NOT”を繋げることで、真偽判定を逆にすることができます。

文字列比較も可能で、下記のように記述します。

数値の比較も可能ですが、比較演算子として”==”の代わりに”equ”(等しい)、”neq”(等しくない)、”lss”(左辺が右辺より小さい)、”leq”(左辺が右辺以下)、”gtr”(左辺が右辺より大きい)、”geq”(左辺が右辺以上)を使うことに注意が必要です。

8.その他の制御

forループやcall・gotoによるジャンプ、exitでのバッチ終了も可能です。
この記事では例を1つ挙げるだけに留めますが、下記はworkフォルダの中の各々のファイルを、順番に C:\tmp\Program.exe の引数として与えて実行する例です。
for文で順番に従って”%%a”にファイル名を格納、”%%a”を第一引数としてmethodルーチンへ飛ばし、methodルーチンでは受け取った引数を C:\tmp\Program.exe の引数として与えて実行、for文が終了したら(全てのファイルに対して処理が終了したら)exitでバッチファイルを終了、ということをしています。


いかがでしたでしょうか?

今回は、新人にWindowsバッチを教えるために、入門的な記事を執筆してみました。
Windowsバッチは文法的にはある意味独特の世界が広がっており、意外と奥が深いのですが、今回は入門者がすぐにWindowsバッチで簡単な制御が行えるようになることを念頭に、内容を絞りました。
ここに書かれていることを使えるようになるだけでも、開発作業の効率化は十分可能ですし、実行環境配布や運用作業に向けたバッチも簡単なものなら作れるようになると思います。

また、経験者でもWindowsバッチの文法を度忘れすることがあるので、そのような時にも見返すと便利なのではないかと思います。

これからも参考になる記事を執筆していきたいと思います!

C#:イベントハンドラとは

イベントハンドラとはC#で標準で用意されている文法であり、イベント送受信の処理を記述するために用意されています。

クラスAでボタンのクリック等のイベントを発行する

クラスBはクラスAからイベントを受け取り業務処理を行う

クラスBは業務処理終了時にクラスAに何かしらの処理を返す

という動きを実現するための文法です。

文法的にはdelegateの応用であり、
public delegate void EventHandler(object sender, EventArgs e);
というdelegateが標準で用意されていると考えて問題ありません。
(自分で上記の定義を行っても同じ動きをします)
なお、”object sender”とは業務処理を行ったオブジェクト、”EventArgs e”とはイベント発行側のクラスに返すデータ、を指します。

上記の通り、イベントハンドラとは、引数に object sender と EventArgs e を持つdelegateです。
そのため、delegateを理解していれば、イベントハンドラの文法も理解できます。
自分で使うかどうかは別として、Visual Studio で Windows Form を作成した時に自動生成されるソースコードや、他の人のソースコードを読む分には問題ないでしょう。

以下、サンプルコードです。

【サンプルコード】

・Program.cs

・EventReceiver.cs

【実行結果】


いかがでしたでしょうか?

イベントハンドラはC#で画面開発をしていると良く出てくる文法なのですが、馴染みのない人も少なくないかと思います。
イベントハンドラはイベント送受信のためのものであること、文法的には以前に紹介したdelegateの応用であることさえ押さえれば、保守開発等で出くわしてもとりあえず対応できるのではないかと思います。

これからも、C#ならではの文法を紹介していきたいと思います!

Eclipse + Maven で Apache POI を用いてExcelファイルを出力する環境の構築(HelloWorldまで)

Apache POI を用いることで、javaでExcelファイルを出力するプログラムを作成することができるようになります。
今回は、環境設定を行い、HelloWorldを試す所まで記事にしました。
ライブラリを落としてきたりパスの設定をするのに手間がかかるので、今回は Eclipse + Maven で設定を行っています。

【Mavenプロジェクトの作成】

1.Eclipseを立ち上げ、ファイル > 新規 > Mavenプロジェクト を選択。

2.「シンプルなプロジェクトの作成」「デフォルト・ワークスペース・ロケーションの使用」にチェックを入れて次に進む。

3.グループIdに任意の名前(プロジェクトを一意に識別する名前)、アーティファクトIdにプロジェクト名を入力し、完了を押下する。

4.作成されたプロジェクトについて、JREシステム・ライブラリー > プロパティー を選択。

5.適切な実行環境を設定(今回は「JavaSE-1.8」を選択)

【ライブラリのインストール・設定】

1.作成されたプロジェクトに存在するpom.xmlを開き、下記のように入力する。


<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
  <modelVersion>4.0.0</modelVersion>
  <groupId>hoge</groupId>
  <artifactId>ProjectName</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>4.1.2</version>
    </dependency>
  </dependencies>
</project>



dependenciesタグを自分で追記する。

dependencyタグ内の記述については、自分で調べる場合はMVNrepositoryで調べる。ライブラリ名で検索すると、dependencyタグの記述する内容が記載されているページにたどり着く。

2.pom.xmlを保存すると、dependencyタグに記載されたライブラリが自動的にインストール・設定される。

【Excelファイルを出力】

1.src/main/java 直下で右クリックし、新規 > クラス を選択。その後、クラス名(今回は「POITestMain」)を入力し、クラスを生成する。

2.下記のようにソースを記述する。

3.クラスを実行すると、ソース内で記述したパスに下記のような内容のファイルが生成される。


実行時にjava.lang.NoClassDefFoundErrorが出る可能性があります(私の環境では出ました)。
その場合は、Eclipseを一度落とし、C:\Users\ユーザ名\.m2 にある repository フォルダを削除し、もう一度Eclipseを立ち上げ、プロジェクトで右クリック > 実行 > Maven Clean を実施し、pom.xmlをもう一度保存し直したりしてみて下さい。
良く起こる事象のようで、「Maven NoClassDefFoundError」でWebで検索すると色々情報が出てきます。


いかがでしたでしょうか?

Apache POIはよく使われているライブラリのようで、Webで検索すると色々と情報が見つかりますが、導入するまでの所で意外とつまずくポイントが少なくないと感じたので、今回の記事を執筆しました。
個人的に、新しい技術を学ぶ時には、「概要の理解→導入→できる限りシンプルなコードで動作確認(多くの場合はHelloWorld)」という流れを大事にしています。
(動いて終わりではなく、なぜ動いたのかを自分で調べて理解することが大事です)
ここまでできれば、詳しい使い方を調べてコードを付け加えていくことで、実務にも耐え得る成果物を作ることができるからです。

これからも、技術を導入する際に役に立つ記事を書いていきたいと思います!

C#:WPFでのHelloWorld

以前の記事では、WindowsFormでのHelloWorldを試しました。
今回の記事では、WPFでのHelloWorldを試してみます。

WPFはWindowsFormの後発にあたるWindows向け画面アプリの形式であり、画面がXAMLというマークアップ言語で記述されていること(C#で記述されている場合に比べて見やすい)、MVVM(UIに対しては単一スレッドでしか操作できない、リストが長く画面に表示しきれない場合に表示されている分のオブジェクトしか生成されない、といったUIの制約を意識せずにビジネスロジックを書くための手法)を実現しやすいこと、が特徴となっています。

以下では、Visual Studio Communityを使用したHelloWorldの手順を紹介します。
操作感はWindowsFormと似ているので、注意する箇所だけ詳細に書きます。
XAMLの項目とクラスの値をバインドさせる(クラスの値が変更された際にXAMLの画面上に反映する)点がミソです。

【手順】

1.Visual Studio Community を開く。

2.「ファイル > スタートページ」でスタートページを表示させ、スタートページ上の「新しいプロジェクトを作成」をクリック。

3.「WPF アプリ」を選択する。名前は任意で良い。これで「OK」を押下すると、「場所」で指定した場所にプロジェクト(作業フォルダ)が生成される。

4.ボタンやラベルを配置する。すると以下のようなXAMLが生成される。

・MainWindow.xaml

5.下記のクラスを作成する。

・MainWindow.xaml.cs

・MainViewModel.cs

・MainModel.cs

※補足

バインドさせる際には、「ReactiveProperty」を使用すると便利です。
自分で「NuGet パッケージの管理」から落とす必要があります。

【実行結果】

ボタン押下で「Hello World!」が表示されます。


いかがでしたでしょうか?

C#の画面アプリと言えばWindows Formという感じがしますが、今から始めるなら機能面で強化されているWPFの方が良いかもしれません。
昔は日本語の文献が少なく導入に苦労するという話もありましたが、現在は文献も充実しており、ネット上でも参考になる文献を見ることができます。

次回も、C#の便利な文法を紹介していきたいと思います!