[tips]BATファイルにJScriptをまとめてすぐ実行できるようにする

WindowsでJScriptを実行しようとすると、「Windows Scripting Host」を利用することになります。

そうした場合、自分でない誰かへ渡して「コマンドプロンプトを起動したらcscriptにこのファイルを引数にして、あとそれから引数が…」なんていう説明をしなければなりません。


実はBATファイルの特性とJScriptの仕様を組み合わせることでひとつのBATファイルにすることができます。

そうすることで、ダブルクリックしてもらうだけで(設定によってはシングルクリックで)実行してもらうことができます。


作り方

仕組みはいたって単純です。

次のようにすればよいのです。

@if(0)==(0) echo off
cscript //nologo /E:JScript "%~f0" %*
goto :EOF

@end

WScript.echo("hello");

コマンドプロンプトでは先頭に「@」記号がついたものはその行の実行を表示しません。

つまり「@if」の行は表示されることなく「(0)==(0)」が評価されます。

これは常にTrue、真になります。ですから「echo off」というコマンドが実行されます。

その後、JScriptを実行するコマンドが続きます。

この実行が終了すると「GOTO」コマンドによってファイルの最後へ制御がジャンプします。ここでBATファイルは終了します。

次に、「cscript」コマンドにより実行されるJScriptですが、ファイルとしては自分自身が実行されます。


自分自身を実行する

なぜそうなるかと言いますと、肝は「%~f0」です。

これがBATファイルそのものを表すことになります。

もともとは%0という引数で、実行されたファイルのことを指します。

ですからBATファイルに「echo "%0"」と書いて実行すると実行したファイル名が表示されます。

では、「~f」部分はなんなのでしょうか?これは引数で与えられた変数をどのように「展開」するかを表しています。

「~」記号が「展開する」を表し、展開の仕方が続きます。

ここでは「f」になっています。これは完全修飾したファイルパス、つまりドライブを含めたパスを表現します。

もしも「p」であれば実行されたファイルが保存されているフォルダのパスが、「d」であればファイルが保存されているドライブが表示されます。

さらに、「n」であればファイル名の拡張子を除いた部分が、「x」であれば拡張子のみが表示されます。組み合わせることもできるようで、「%~nx0」は「%0」と同じ結果になります。

もしもJScriptへ実行時引数を渡すとしても大丈夫です。

「%*」という記載が最後にあると思います。

これは「ファイル実行時に与えられたすべての引数」を表します。ですからこのBATファイルをコマンドプロンプトから実行したときに与えた引数はすべてJScriptへ引き継ぐことができます。


JScriptはどのように実行されるか

さて、ではJScriptとして実行されたとき、このファイルはどのように解釈されるのでしょうか?

JScriptには仕様として「@if - @end」という条件付きコンパイルを行う構文があります。

つまり、条件に合致した場合だけこのブロック内は実行されることになります。しかし、上記のコードでは条件に合致することはありません。結果として、「@end」までのコードはすべて無視されます

ということで、「@end」以降の部分だけがJScriptとして実行できるのでした。


この手法の問題点

この手法を利用して実際にスクリプトをつくってみるとわかるのですが、優秀なエディタを利用していても拡張子をBATにしてしまうとBAT用の構文ハイライトがなされます。

また、拡張子を「js」にしてしまうとJavaScript用の構文ハイライトがされてしまうので非常に見づらいです。

それに、テストもしにくいですね。


簡単な解決方法

考えてみれば、自分以外の誰かが使うときだけBATファイル1つになってくれていればいいのです。そうなのであれば、最初から別々に作って結合すればいいでしょう。

別々に作ってしまい、最終的に配布するタイミングになったら結合します。

何もテキストエディタで開いてコピーしてもいいのですが、コマンドプロンプトからでもできます。

元になるBATファイルを用意しておきます。ここでは「template.bat」でもいいでしょう。

コードは以下のとおりです。

@if(0)==(0) echo off
cscript //nologo /E:JScript "%~f0" %*
goto :EOF

@end

あとはJScriptファイルがあればいいですね。ここでは例として「example.js」にしましょう。

コマンドプロンプトから次のようにすれば「example.bat」の完成です。

copy /B template.bat + /B example.js example.bat

Windowsのコピーコマンドにはファイルを結合する機能があります。「/B」オプションはバイナリファイルとして扱うというものなのですが、各ファイルの文字コードがどうなるかわからないのでこうしておくと無難でしょう。

ひとつ注意が必要なのが、順番です。必ずテンプレートになるBATファイルを先頭にしましょう。そうしなければコマンドプロンプトはJScript部分を最初に評価してしまうことになりますよ。

もんが(なるーらぼ)

個人でプログラミングの学習サイト「なるーらぼ」を運営しています。
https://nalu-labo.amebaownd.com
PowerShell入門の電子書籍2冊も出版しています。
http://www.amazon.co.jp/dp/B017LJOCJ2

なるーらぼ

ごく自然にプログラミングを楽しむことができる世界をつくるお手伝いをしています

0コメント

  • 1000 / 1000