= 実行ファイルのラッパー「wrapexec」 =
[[Embed(http://static.sourceforge.jp/thumb/g/0/552/640x640_0.png, caption=)]]
== 概要 ==
wrapexecは、他のプログラムを単に実行するだけのプログラムです。どのプログラムをどのように実行するかを、設定ファイルにより定義できます。
== このプログラムが役に立つケースの例 ==
例えば Perl で有用なツールを作ったとします。仮に、useful_script.plという名前をつけたとしましょう。さて、これを実行しようとするたびに、毎回「perl useful_script.pl 云々・・・」と打つのは面倒です。そこで、wrapexec.exe を useful_script.exe という名前でコピーして設定ファイルを記述してやると、単に「useful_script 云々・・・」と打つだけでスクリプトを実行することができます。
また、スクリプトをプログラムのように扱う手法として、スクリプトの冒頭に特別な記述を挿入し、バッチファイルにしてしまうというテクニックもよく用いられます。しかしこの場合、つまるところバッチファイルですから、それを他のバッチファイルから呼ぶときは、単に「useful_script」などと記述したのでは、呼び出し元のバッチファイルに戻ってきてくれません。バッチファイルであることを意識して、「call useful_script」などと記述する必要があります。[[BR]]
(MS-DOS時代から連綿と続く、おそるべき仕様)[[BR]]
このような場合も、wrapexec を介して useful_script.bat を呼ぶようにすれば解決します。wrapexec は通常のexeファイルですので、バッチファイルから実行された場合でも、呼び出し元のバッチファイルに制御が戻ります。
CUIに慣れている人は、Program Files 以下にインストールされたエディタやツール類を、コマンドラインから実行したいと思うことが多々あると思います。ところが Program Files 以下には通常、PATHは通っていません。[[BR]]
そもそも Program Files 以下は通常、ソフトウェアごとにディレクトリが切られますので、それらひとつひとつにPATHを通していては大変です。[[BR]]
このような場合は、どこかパスの通ったディレクトリに warpexec.exe を(word.exe でも access.exe でも適当な名前で)コピーして、そこからProgram Files 以下の本物のプログラムを実行するようにすることで、あたかもそのプログラムにPATHを通したかのようなことができます。
実行したいプログラムが、/bin にあるのか、/usr/bin にあるのか、それとも/usr/local/bin はたまた /opt/theSoftware/bin にあるのか といった問題は Windows では比較的発生しにくいのですが、それでも環境や運用方法によっては、実行したいプログラムの実体がどこにあるのかが特定できない場合があります。例えば、実行するマシンによって、perl.exe や cc.exe の場所が異なる現場など。[[BR]]
wrapexec は、実行するプログラムの候補を複数指定できますので、考えられる場所をあらかじめ列挙しておくことで、それらのうちのどこかにあればそれを実行するということができます。
あるプログラムを実行するとき、必ずそれに先立って初期化処理を行いたいというケースがあるかと思います。例えば、常に同じ設定で起動するために、レジストリをクリアしておきたい など。[[BR]]
wrapexec は、複数のプログラムを実行できます。本体のプログラムを実行する前に、任意のバッチファイルやスクリプトを実行して、思う存分お膳立てをすることができます。
このように、かように単純なプログラムでも、こと Windows で cmd.exe を使っている場合はけっこう役に立ちます。
== 用途 ==
exeファイルに対するラッパとして使えます。他の場所にあるexeファイルを同じオプションで実行したり、または追加のオプションを与えたり、そのexeのあるディレクトリにchdirしたうえで実行したりといったことができます。また、GUIアプリケーションについては、最小化/最大化するよう指示を与えたうえで起動することもできます。
batファイルに対するラッパとして使えます。バッチファイルを他のバッチファイルから実行する場合、「call バッチファイル名」としないと、呼び出し元のバッチファイルに制御が戻らず、バッチファイルの処理がそこで終了してしまいますが、このプログラムを介してバッチファイルを実行することにより、本体はバッチファイルだとしても、そうと意識せずに他のバッチファイルから実行することができます。[[BR]]
また、callで呼び出されたバッチファイル内では、環境変数を操作したり、カレントディレクトリを変更したりすると、呼び出し元のバッチファイルの側にもその影響が現れますが、このプログラムを介してバッチファイルを実行した場合、別個のcmd.exeの下でバッチファイルが実行されますので、上記のような副作用はありません。[[BR]]
(逆に、そのような副作用を前提としたバッチファイルは、本プログラムを介して実行すると、もともと意図されたようには動作しません)[[BR]]
なお、デフォルトの状態では、環境変数 PATHEXT= において .exe が .batよりも先に記述されているため、同じ名前のバッチファイルが存在したとしても、exe の方が実行されます。(明示的に拡張子を指定した場合を除く)
その他のスクリプトに対するラッパとして使えます。スクリプト名と同じ名前で本プログラムをコピーして、対象のスクリプト言語のインタプリタを実行し、その引数には、実行したいスクリプト名を与えるよう設定します。これにより、あたかもスクリプト自体に実行属性を与えたかのように、直接実行する(のに似た)ことができます。[[BR]]
Perl や Ruby などのインタプリタによっては、「ファイル冒頭の特定の記述までを読み飛ばす」という機能があるものがあります。一方、本プログラムは、「ファイルの特定の記述(![eof])以降を読み飛ばす」という機能があります。[[BR]]
これを組み合わせると、本プログラムの設定ファイルと、スクリプト本体を、ひとつのファイルに記述できます。
これらの結果として、コマンドプロンプトがCUIのランチャになります。パスの通ったディレクトリに、よく使うアプリケーションをそれぞれラップした本プログラムを入れておけば、どこにいても、プログラム名だけで、実体はそれぞれどこか別のところにあるプログラムを一発で実行することができます。スタートメニューや Program Files の中を探し回ったり、ネットワークのドライブ文字を慌てて調べたりする必要はありません。
== 動作環境 ==
* WindowsNT 4.0以降 (2000/XP/Vista等)。
* 動作確認はWindowsXP上で行っています。
== 使用法 ==
本プログラムは、提供時は wrapexec.exe というファイル名ですが、実際に使用する際は、別の名前にコピーされることを想定しています。[[BR]]
名前はなんでもよいですが、通常は、実行したい(ラップしたい)プログラムと同じ名前でコピーするのがよいかと思います。
次にその設定ファイルを作成します(書法は後述)。コピーした本プログラムと同じディレクトリの、同じ名前で拡張子を .ini に置き換えたファイルが、設定ファイルとして使われます。
あとはそのコピーした本プログラムを実行すれば、設定ファイルに従って目的のプログラムが実行されます。
== 設定ファイル(.ini) ==
実行ファイルの拡張子を .ini に置き変えたファイルを設定ファイルとして読み込みます。
このファイルは、UNICODEのUTF-8で作成する必要があります。
書式は Windows でよくある、INIファイルに似たものです。[section] でセクションを宣言し、それ以降にその内容を記述します。キーワードの大文字小文字は区別されません。[[BR]]
いくつかの箇所では、${変数名}の形式で、マクロを使用できます。(後述)[[BR]]
行頭および行末のスペースは無視されます。[[BR]]
'#' または ';' で始まる行はコメントです。なお、行中の '#' ';' はコメントの開始文字としては扱われないことに注意して下さい。つまり:
{{{ pre
# この行はコメントです。
; 行頭のスペースは無視されるので、
; この行もコメントです。
gui = true # これはコメントとは解釈されません。
}}}
使用可能なセクションは以下の通りです。
'''![option] セクション'''[[BR]]
このセクションでは、プログラムを実行するときの様々な動作を、キーワード=値 の書式で記述します。「=値」は省略することもできます。[[BR]]
使用可能なキーワードとその意味については後述します。
'''![exec] セクション'''[[BR]]
実行したいプログラム(のいくつかの候補)を記述します。[[BR]]
マクロ(${MY_DIR}等)を使用できます。[[BR]]
複数行、記述することができます。記述された順にファイルの存在チェックを行って、最初に見つかったものを実行します。この時、環境変数 PATH を参照してのサーチは行いませんので、注意して下さい。[[BR]]
ここで自分自身を指定すると、無限ループになりますので注意して下さい。
'''![global] セクション'''[[BR]]
上記の ![option] ![exec] セクションの組は、ひとつの設定ファイルの中に複数個記述することができます。![option] セクションで記述した内容は、その ![option] ![exec] セクションの組についてだけ有効なので、複数の ![option] ![exec] セクションの組に共通で与えたいオプションがあるときは、この ![global] セクションで記述することで、それ以降の全ての ![option] セクションで個別に指定したのと同じことになります。
'''![eof] セクション'''[[BR]]
ここで設定ファイルの読み込みを終え、これより後に何が書かれていても無視するようにします。[[BR]]
設定ファイルに、実行したいスクリプト本体を埋め込みたい時などに便利な場合があります。
== オプション ==
オプションには、引数に真偽値をとるものと、文字列をとるものとがあります。[[BR]]
真偽値をとるオプションの場合、"true" "yes" "on" が真、"false" "no" "off" が偽と解釈されます。また、引数を与えなかった場合は、真として扱われます。[[BR]]
文字列をとるオプションの場合、"=" 以降がそのまま引数として解釈されます。また、引数を与えなかった場合は、空文字列として扱われます。
例
{{{ pre
[option]
verbose=true (真)
internal=no (偽)
gui (引数が省略されたため、真)
chdir=C:\work ("C:\work" という文字列)
}}}
![option] および ![global] セクションで使用可能なオプションは、以下の通りです。
'''help'''[[BR]]
特殊なオプションです。このオプションを指定すると、簡単なヘルプを表示して終了します。[[BR]]
本プログラムの性質上、コマンドラインから "--help" などとしても、本プログラムがヘルプを表示するようなことはなく、それはそのまま本プログラムから実行されるプログラムに渡されることになります。
'''arg (初期値:"${ARG}")'''[[BR]]
引数に文字列をとります。本プログラムから実行されるプログラムに引数をどのように渡すかを指定します。デフォルトは "${ARG}" で、これは本プログラムに渡された引数をそのまま渡すことを意味します。[[BR]]
マクロ(${ARG}等)を使用できます。
'''chdir (初期値:"")'''[[BR]]
引数に文字列をとります。プログラムを実行する前にカレントディレクトリを変更したい場合に、このオプションで移りたいディレクトリを指定します。UNCパス(\\server\share等)も指定できますが、UNCパスに直接 chdir することはできませんので、一時的に空いているドライブ文字を割り当てた上で、そこに chdir します。[[BR]]
マクロ(${MY_DIR}等)を使用できます。
'''import_env (初期値:定義なし)'''[[BR]]
引数に文字列をとります。このオプションを使うと、環境変数を後述のマクロとして使うことができます。これにより、環境変数の内容によって本プログラムから実行されるプログラムを切り替えたり、オプションを切り替えたりといったことができます。[[BR]]
このオプションは複数個指定できます。
'''export_env (初期値:定義なし)'''[[BR]]
引数に文字列をとります。このオプションを使うと、後述のマクロの値を環境変数に設定した上で、プログラムを実行できます。環境変数は、マクロの名前の頭に "WRAPEXEC_" をつけた名前になります。[[BR]]
例えばマクロ ${ARG} を、export_env=ARG としてエクスポートすると、本プログラムへ渡された引数が、環境変数 WRAPEXEC_ARG に設定されます。[[BR]]
このオプションは複数個指定できます。
'''verbose (初期値:false)'''[[BR]]
引数に真偽値をとります。値が真の場合、内部処理の状況と状態を逐一表示します。設定ファイルの動作確認の際に使用すると役立つことがあります。
'''internal (初期値:false)'''[[BR]]
数に真偽値をとります。値が真の場合、実行されるプログラムは cmd.exe の内部コマンドであるとみなされます。例えば、echo や set を実行したい場合、これらは cmd.exe の内部コマンドですので、ファイルとして echo.exe や set.exe があるわけではありません。[[BR]]
本プログラムは通常、実行しようとするファイルが実際に存在することを確認してから実行しますので、そのままでは echo や set が実行されません。[[BR]]
(プログラムが見つからない旨のエラーメッセージが出力されます)[[BR]]
そのような場合、このオプションを指定すると、ファイルの存在チェックを省略して実行します。
'''gui (初期値:false)'''[[BR]]
引数に真偽値をとります。値が真の場合、実行されるプログラムは Windows の GUI のプログラムとみなされ、cmd.exe の start コマンドにより 別ウィンドウで起動されます。また、下記の wait オプションが真でない限り、実行されたプログラムの終了を待たず、本プログラムはすぐ終了します。
'''wait (初期値:false)'''[[BR]]
引数に真偽値をとります。本オプションは、前述のオプション gui が真の場合のみ意味を持ちます。値が真の場合、本プログラムから実行されたプログラムが終了するまで、そのまま待機します。(通常、本プログラムはすぐ終了します)
'''maximize (初期値:false)'''[[BR]]
引数に真偽値をとります。本オプションは、前述のオプション gui が真の場合のみ意味を持ちます。値が真の場合、ウィンドウを最大化して起動するよう、実行されるプログラムに指示します。[[BR]]
これを指定すると、minimize が false になります。
'''minimize (初期値:false)'''[[BR]]
引数に真偽値をとります。本オプションは、前述のオプション gui が真の場合のみ意味を持ちます。値が真の場合、ウィンドウを最小化して起動するよう、実行されるプログラムに指示します。[[BR]]
これを指定すると、maximize が false になります。
== マクロ ==
設定ファイル中のいくつかの場所では、${名称} の形式で、マクロ展開を使用することができます。[[BR]]
「${」という文字列そのものを表すには、「$${」と記述します。[[BR]]
「${名称}」の他、「$(名称)」「$![名称]」の書式も使用できますが、「$名称」の書式は使用できません。必ず括弧で括る必要があります。[[BR]]
マクロ展開は一度だけ行われ、展開された文字列が再びマクロ展開されることはありません。
標準で使用できるマクロは以下の通りです。
'''ARG'''[[BR]]
本プログラムに与えられたコマンドライン引数。(プログラム名以降の部分)[[BR]]
プログラム名と引数の間のスペースも含まれることに注意して下さい。[[BR]]
例えば、{{{"wrapexec.exe FooBarBaz"}}} として実行した場合、${ARG} は[[BR]
{{{" FooBarBaz"}}} に展開されます。[[BR]]
コマンドラインで与えられた、スペースの個数や特殊記号、UNICODE文字等もそのまま忠実に再現して同じものが展開されます。
'''CLIPBOARD'''[[BR]]
プログラム実行時のクリップボードの値。[[BR]]
クリップボードの内容がテキスト以外だった場合は、空文字列となります。[[BR]]
改行やタブ文字などのホワイトスペース文字は、スペースに置換されます。
'''MY_EXENAME'''[[BR]]
自分自身 (wrapexec.exe) のフルパスファイル名。[[BR]]
例 : {{{D:\somewhere\wrapexec.exe}}}
'''MY_ININAME'''[[BR]]
設定ファイルのフルパスファイル名。[[BR]]
例 : {{{D:\somewhere\wrapexec.ini}}}
'''MY_BASENAME'''[[BR]]
自分自身 (wrapexec.exe) のベース名(ドライブ名、パス名、拡張子を除いた名前)。[[BR]]
例 : {{{wrapexec}}}
'''MY_DIR (別名 : MY)'''[[BR]]
自分自身 (wrapexec.exe) のパス名。(ドライブ名および末尾の'\'を含む)[[BR]]
例 : {{{D:\somewhere\}}}
'''MY_DRIVE'''[[BR]]
自分自身 (wrapexec.exe) のあるドライブ名。[[BR]]
例 : {{{D:}}}
'''SYS_NAME'''[[BR]]
コンピュータ名。[[BR]]
例 : {{{SOMEONESPC}}}
'''SYS_ROOT'''[[BR]]
システムのルートディレクトリ。[[BR]]
例 : {{{C:\WINDOWS\}}}
'''SYS_DIR (別名 : SYS)'''[[BR]]
システムディレクトリ。[[BR]]
例 : {{{C:\WINDOWS\system32\}}}
'''SYS_DRIVE'''[[BR]]
システムドライブ。[[BR]]
例 : {{{C:}}}
'''USER_NAME'''[[BR]]
ユーザ名。[[BR]]
例 : {{{someone}}}
'''USER_DIR (別名 : USER)'''[[BR]]
ユーザのプロファイルのディレクトリ。[[BR]]
例 : {{{C:\Documents and Settings\someone\}}}
'''USER_DRIVE'''[[BR]]
ユーザのプロファイルのあるドライブ。[[BR]]
例 : {{{C:}}}
'''USER_DOC'''[[BR]]
ユーザのマイドキュメントのディレクトリ。[[BR]]
例 : {{{C:\Documents and Settings\someone\My Documents\}}}
'''USER_DESKTOP'''[[BR]]
ユーザのデスクトップのディレクトリ。[[BR]]
例 : {{{C:\Documents and Settings\someone\デスクトップ\}}}
'''ALL_USER_DIR (別名 : ALL_USER)'''[[BR]]
共通のプロファイルのディレクトリ。[[BR]]
例 : {{{C:\Documents and Settings\All Users\}}}
'''ALL_USER_DRIVE'''[[BR]]
共通のプロファイルのあるドライブ。[[BR]]
例 : {{{C:}}}
'''ALL_USER_DOC'''[[BR]]
共有ドキュメントのディレクトリ。[[BR]]
例 : {{{C:\Documents and Settings\All Users\Documents\}}}
'''ALL_USER_DESKTOP'''[[BR]]
共通のデスクトップのディレクトリ。[[BR]]
例 : {{{C:\Documents and Settings\All Users\デスクトップ\}}}
'''PROGRAM_DIR (別名 : PROGRAM)'''[[BR]]
プログラムフォルダのディレクトリ。[[BR]]
例 : {{{C:\Program Files\}}}
'''PROGRAM_DRIVE'''[[BR]]
プログラムフォルダのあるドライブ。[[BR]]
例 : {{{C:}}}
'''TMP_DIR (別名 : TMP)'''[[BR]]
テンポラリディレクトリ。[[BR]]
例 : {{{C:\DOCUME~1\SOMEONE\LOCALS~1\Temp\}}}
'''TMP_DRIVE'''[[BR]]
テンポラリディレクトリのあるドライブ。[[BR]]
例 : {{{C:}}}
上記の他、オプション import_env で、任意の環境変数をマクロ展開に使用することができます。
個々の環境での具体的な値は、オプション verbose を真と設定すると確認することができます。
== 設定ファイル記述例 ==
Perlスクリプト theScript.pl を実行する例
(本プログラムと同じディレクトリに theScript.pl が存在するものとする)
{{{ pre
[option]
arg="${MY_DIR}theScript.pl"${ARG}
[exec]
c:\Perl\bin\perl.exe
}}}
設定ファイルの後半に書かれた Rubyスクリプトを実行する例
{{{ pre
[option]
arg=-x "${MY_ININAME}"${ARG}
[exec]
c:\Ruby\bin\ruby.exe
[eof]
#!ruby
p "Hello World!"
}}}
Program Files の奥底にある !MyFavoriteEditor.exe を最大化して実行する例
{{{ pre
[option]
gui
maximize
[exec]
${PROGRAM}folder\to\program\MyFavoriteEditor.exe
}}}
どこかにある gypsy.exe を実行する例
{{{ pre
[exec]
${SYS}gypsy.exe
${PROGRAM}gypsy\gypsy.exe
c:\somewhere\gypsy.exe
c:\anotherwhere\gypsy.exe
\\far\shere\gypsy.exe
}}}
レジストリをクリアしてから 目的のプログラムを実行する例
{{{ pre
[option]
arg=${MY_DIR}initialize.reg
[exec]
${SYS_ROOT}regedit.exe
[exec]
target.exe
}}}
名前順でソートする dir コマンドの例
{{{ pre
[option]
internal
arg=/on${ARG}
[exec]
dir
}}}
== 使用上の注意 ==
本プログラムはなるべく意図した通りに動作するよう心がけて作成していますが、設定ファイルの誤りやその他の原因で、意図せぬプログラムを意図せぬオプションで実行してしまうことが、絶対にないとはいえません。必ず充分な動作確認を行ったうえで使用してください。
本プログラムはその目的上、設定ファイルを書き換えることにより多様な動作をさせられるため、その取り扱いには注意して下さい。万一、悪意ある第三者に設定ファイルを改竄された場合の影響は計り知れません。
== 欠点 ==
普通にプログラムを実行するより、ややメモリを多く消費します。本プログラム および コマンドを実行するために使用している cmd.exe がそれぞれメモリを消費するためです。
== 既知のバグおよび今後の課題 ==
SourceForge.jp 内の チケットシステムを参照してください。
== 謝辞 ==
記載の社名、製品名は各社の商標または登録商標です。
このプログラムは、Borland C++ でコンパイルされています。
このプログラムは、UPX で圧縮されています。
== 権利 ==
Copyright (c) 2009 by opa[[BR]]
All rights reserved.
ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満たす場合に限り、再頒布および使用が許可されます。
* ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項を含めること。
* バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作権表示、本条件一覧、および下記免責条項を含めること。
* 書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進に、作者(おぱ)の名前またはコントリビューターの名前を使用してはならない。
本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありません。著作権者もコントリビューターも、事由のいかんを問わず、損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する可能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、一切責任を負わないものとします。
----