同じコンバート処理を繰り返し行うには?データビルドは、一度実行すると自動的にどばーっと作業を進め、最終的にはゲームで使用する専用データを完全に作ってくれます。細かく見れば、その作業は「あるファイルに対するコンバート作業」の連続です。データビルドの仕組みを作る上で、同じコンバート処理を繰り返し行わせる事が必須となるわけです。この章では、そういう連続した作業を行わせる方法について見て行きます。実行ファイルをforループで連続実行する方法プログラムで同じ作業を繰り返し行うというと、forループが真っ先に思いつくと思います。言う事は、コンバータに沢山のファイル情報(ファイルパス)を渡せば、forループ内で連続的なコンバート作業を行わせる事ができそうです。それは正しい方法の一つかなと思います。別の方法もあるんです。コンバータは余り複雑な事をしない方が作るのが楽です。ファイルを一つもらったら、コンバートしたファイルを一つ作って返す。そんな軽量なコンバータの方が簡単に作れます。このコンバータを連続して動かすには必然的に「何百回もexeを実行する」という、「起動のforループ」が必要になります。起動を何百回も行わせる方法は色々とあります。コマンドラインにforループが書けるので、それを使う方法ももちろんありです。そんな中で私が経験し、「これは自由度が高いなぁ」と感じたのが「スクリプト言語を通したバッチ処理」でした。「JScript」というWindowsが入っていれば誰でも使える超超便利なスクリプトがあります。今回はこれを中心に話を進めて行くことにします。!JScriptは数あるスクリプト言語の一つで、Windowsのシステムを使って色々な事をさせるのが得意です。特定のファイルだけを選択して別のフォルダにコピーする、Excelファイルに対するダイレクトな書き込み、ネットワークのやりとりなどなど、非常に柔軟に様々な事ができるんです。外部のexeファイルを実行させることもできます。JScriptはテキストファイルで簡単に書く事ができます。!」と描画するJScriptを作ってみましょう。適当なフォルダ(HelloWorldフォルダとしておきます)を作り、そこに「HelloWorld.js」という空のファイルを新規に作ります。!");たった1行ですが、立派なスクリプトです。WScript.Echo関数は、コマンドラインに引数の文字列を描画します。printfと同じですね。次に、同じフォルダ内に「HelloWorld.bat」というバッチファイルを一つ作ります。HelloWorld.jspausecscriptというのはcscript.exeという実行ファイルを起動させる事を表しています。この実行ファイルは引数(HelloWorld.js)のJScriptを動かしてくれます。2行目のpauseはバッチ処理の一時停止で、結果を見るために置いておきました。HelloWorldフォルダの中にHelloWorld.jsとHelloWorld.batという2つのファイルがある状態で、バッチファイルを実行してみましょう。!」と表示されました。JScriptがちゃんと動いたわけです。こんな感じで、基本的にはバッチファイルにスクリプトを実行してもらうのがわかりやすいかなと思います。JScriptは言語なのでループや条件分岐をもちろん備えています。JScript内から外部のexeを実行させる事もできるんです。Host(WSH)」という仕組みを借ります。これはActiveXコンポーネントの一つですが、こ難しいことは置いておいて、使い方をざっくり知ってしまいましょう。例として、メモ帳をJScriptから開いてみます。空っぽのOpenNotePad.jsとOpenNotePad.batファイルを作ります。batファイルは�Aの時と同じでcscriptの引数にOpenNotePad.jsを渡しておきます。{WScript.Sleep(100);}varというのはJScriptで使用される変数宣言で、何でも表せる万能型です。ActiveXObjectというのがActiveXオブジェクトを作っている部分です。JScriptはJavaScriptの一部(の拡張)になっているので、書き方はJavaやC++にそっくりなんです。外部exeを実行する機能を持っているのはWScript.ShellというActiveXオブジェクトです。このオブジェクトのexecメソッドが実行ファイルを扱えます。メモ帳はデフォルトではC:\Windows\System32\notepad.exeにありますので、そのメソッドにパスを与えます。すると、この行が処理されればメモ帳が開きます!execメソッドの戻り値をexec変数に保持しています。この戻り値は実行したexeの状態を監視してくれます。exec.Statusにその状態が入っていますので、ループで監視しています。exec.Stateが0意外になったら閉じた事になります。実際にこのスクリプトを動かしてみると、コマンドプロンプトと一緒にメモ帳が開くのが確認できるはずです。メモ帳を閉じたら、コマンドプロンプト側のバッチ処理が進みpauseが処理されるのが分かると思います。ここまで来ると、もう言わずもがなかもしれませんが、起動部分と待機部分を囲むforループを作れば、処理が一つ一つ進むスクリプトになるわけです。ノートパッドの場合は、こちらから閉じるボタンを押さないと処理がすすみませんが、コンバータは普通処理を終えると勝手に終了するように作るため、黙っていてもどんどんループ処理が遂行されていきます。これで連続実行はできそうです。後は、沢山のファイル(パス)をJScriptで取得できれば、ファイルを一つ一つ処理するという事ができるようになります。JScriptでフォルダ内のファイルパスを列挙するJScriptはWindowsのシステム処理を色々と動かせるので、もちろんファイル処理もできます。連続処理をするには特定のフォルダにあるファイルパスをどばーっと取得する仕組みが欲しいところです。これも、わりと簡単なんです(^-^)。適当なフォルダ(EnumFile)にEnumFile.jsとEnumFile.batファイルを作ります。検索するフォルダとしてresourceフォルダを作り、その中に適当なファイル(text01.txt、text02.txtなど)を入れておきましょう。バッチファイルはもう大丈夫ですよね。i++)WScript.Echo(filePathAry[i]);Scripting.FileSystemObjectというのはファイル操作を担当するActiveXオブジェクトです。JScriptの配列はかなり自由度が高くて色々な宣言方法があるのですが、今は上のfilePathAryのような簡便法を使うことにします。fs.GetFolderメソッドに検索したいフォルダパスを与えるとそのフォルダ内の様々な情報を持ったフォルダオブジェクトを返してくれます。そのフォルダオブジェクト(folderObj)はFilesというメンバを持っていて、これをEnumeratorという列挙してくれる人に渡すと列挙オブジェクトが出来上がります(files)。列挙オブジェクトは保持している物をitemメソッドを通して一つずつ取り出す人です。while文の中ではfiles.item()でファイルパスを一つ取り出します。それを配列に格納(filePathAry.pushメソッド)しています。files.moveNextを呼ぶと、次のファイルパスに列挙が移動します。これを繰り返せばフォルダ下のファイルパスが全部手に入ります。files.atEndメソッドがtrueになったら、もう列挙できるファイルパスが無くなっているのでループから抜けます。後は配列に格納したファイルパスを一つずつ取り出して出力しているだけです。これだけのコードでフォルダ下のファイルパスが手に入るのですから楽なもんです。これで「exeを連続で起動する」という処理と、「フォルダ下のファイルパスを列挙する」という処理ができるようになりました。本章の総まとめとして、簡単な暗号化アプリケーションをC++で作り、特定フォルダ下のファイルを全部暗号化して別のフォルダに保存するデータビルドの仕組みを作ってみましょう。暗号化データビルド今回の暗号化はサンプルなので、ファイルをバイナリとして開き、1byteずつデータを取り出し、その値に1足してファイルとして出力する簡単なものにします。コンソールアプリケーションで作ってしまいます。0;}コマンドライン引数に入力ファイルパスと出力ファイルパスを渡すと、入力ファイルを暗号化して出力ファイルへ書き込みます。このソースをコンソールアプリケーションとしてビルドしてSampleEncryption.exeという実行ファイルを作っておきます。テストをするとこんな感じです:上はコマンドラインを手打ちしたわけですが、これをJScriptさんに自動的にやってもらおうというわけです。JScript側の作業に移ります。適当なフォルダ(Encryptionフォルダ)を作り、もうすっかりおなじみになったと思いますが、空のEncryption.batとEncryption.jsファイルを作成します。暗号化実行ファイルであるSampleEncryption.exeも同じフォルダ内に入れておきます。今回はこのフォルダ下にあるresourceフォルダ内の全ファイルを暗号化してEncryptedフォルダに格納するデータビルドを作ってみることにします。Encryptionフォルダ内は次のような構成になります:バッチファイルはEncryption.jsを実行するだけです。"]");}短いスクリプトです。ActiveXオブジェクトを作成しています。次にresourceフォルダ内の操作を行うフォルダオブジェクトをfs.GetFolderメソッドで取得しています。このオブジェクト内にすでにファイル名リストがあります(fokderObj.Files)。これを列挙してくれるのがEnumeratorです。while文を通してそのファイルパスをfilePathAry配列に全部格納します。次に集めたファイルパスを使って暗号化実行ファイルを連続実行させています。wsh.execメソッド部分が肝です。<出力ファイルパス>という並びにしています。出力ファイルパスは本当はちゃんと命名規則に従ったファイル名にするべきなのですが、今回はサンプルなので単に拡張子の後ろに"enc"を付記するに留めました。暗号化には多少なりとも時間がかかりますので、処理が終了するまで待ちます。この時exec.StdOut.ReadAll()というメソッドを呼び出してそれをEchoしていますが、このメソッドは.exe内でprintf等の標準出力が出力した文字列をコンソールに描画します。個のメソッドを通さないと、コンソール画面に何も表示されません。処理が終了したら終了した旨を告げています。これを前ファイルに対して処理しています。実際に先のフォルダ構成内のEncryption.batを実行すると、resourceファイル内にある複数のファイルに対していっぺんに暗号化が行われ、rencyptedフォルダ内に格納されます:本章では、データビルドを構築する上でかかせない「処理の自動化」について、JScriptを用いる方法を見てきました。本章で挙げたサンプルはすべてこちらからダウンロードできますので、試しに動かしてみると感じがつかめると思います(^-^)。