Show page source of Manual #41319

== 実行ファイルのラッパー「wrapexec」 ==

== by おぱ (opa) ==

= 概要 =

wrapexecは、他のプログラムを単に実行するだけのプログラムです。どのプログラムをどのように実行するかを、設定ファイルにより定義できます。


= このプログラムが役に立つケースの例 =

例えば Perl で有用なツールを作ったとします。仮に、useful_script.plという名前をつけたとしましょう。さて、これを実行しようとするたびに、毎回「perl useful_script.pl 云々・・・」と打つのは面倒です。
そこで、wrapexec.exe を useful_script.exe という名前でコピーして設定ファイルを記述してやると、単に「useful_script 云々・・・」と打つだけでスクリプトを実行することができます。

また、スクリプトをプログラムのように扱う手法として、スクリプトの冒頭に特別な記述を挿入し、バッチファイルにしてしまうというテクニックもよく用いられます。しかしこの場合、要するにバッチファイルですから、それを他のバッチファイルから呼ぶときは、単に「useful_script」などと記述しても、呼び出し元のバッチファイルに戻ってきてくれません。
バッチファイルであることを意識して、「call useful_script」などと記述する必要があります。(MS-DOS時代から連綿と続く、おそるべき仕様)
このような場合も、wrapexec を介して useful_script.bat を呼ぶようにすれば解決します。wrapexec は通常のexeファイルですので、バッチファイルから実行された場合でも、呼び出し元のバッチファイルに制御が戻ります。

CUIに慣れている人は、Program Files 以下にインストールされたエディタやツール類を、コマンドラインから実行したいと思うことが多々あると思います。ところが Program Files 以下には通常、PATHは通っていません。
そもそも Program Files 以下は通常、ソフトウェアごとにディレクトリが切られますので、それらひとつひとつにPATHを通していては大変なことになってしまいます。
このような場合は、どこかパスの通ったディレクトリに warpexec.exe を(word.exe でも access.exe でも適当な名前で)コピーして、そこからProgram Files 以下の本物のプログラムを実行するようにすることで、あたかもそのプログラムにPATHを通したかのようなことができます。

実行したいプログラムが、/bin にあるのか、/usr/bin にあるのか、それとも/usr/local/bin はたまた /opt/theSoftware/bin にあるのか といった問題は Windows では比較的発生しにくいのですが、それでも環境や運用方法によっては、実行したいプログラムの実体がどこにあるのかが特定できない場合があります。例えば、実行するマシンによって、perl.exe や cc.exe の場所が異なる現場など。
wrapexec は、実行するプログラムの候補を複数指定できますので、考えられる場所をあらかじめ列挙しておくことで、それらのうちのどこかにあればそれを実行するということができます。

あるプログラムを実行するとき、必ずそれに先立って初期化処理を行いたいというケースがあるかと思います。例えば、常に同じ設定で起動するために、レジストリをクリアしておきたい など。
wrapexec は、複数のプログラムを実行できます。本体のプログラムを実行する前に、任意のバッチファイルやスクリプトを実行して、思う存分お膳立てをすることができます。

このように、かように単純なプログラムでも、ことWindowsでCMD.EXEを使っている場合はけっこう役に立ちます。


= 用途 =

	exeファイルに対するラッパとして使えます。他の場所にあるexeファイルを
	同じオプションで実行したり、または追加のオプションを与えたり、
	そのexeのあるディレクトリにchdirしたうえで実行したりといったことが
	できます。
	また、GUIアプリケーションについては、最小化/最大化するよう指示を
	与えたうえで起動することもできます。

	batファイルに対するラッパとして使えます。バッチファイルを他のバッチ
	ファイルから実行する場合、「call バッチファイル名」としないと、
	呼び出し元のバッチファイルに制御が戻らず、バッチファイルの処理が
	そこで終了してしまいますが、このプログラムを介してバッチファイルを
	実行することにより、本体はバッチファイルでも、そうと意識せずに他の
	バッチファイルから実行することができます。
	また、callで呼び出されたバッチファイル内では、環境変数を操作したり、
	カレントディレクトリを変更したりすると、呼び出し元のバッチファイルの
	側にもその影響が現れます。
	このプログラムを介してバッチファイルを実行した場合、別個のcmd.exeの
	下でバッチファイルが実行されますので、上記のような副作用はありません。
	(逆に、そのような副作用を前提としたバッチファイルは、本プログラムを
	 介して実行すると、もともと意図されたようには動作しません)
	なお、デフォルトの状態では、環境変数 PATHEXT= において .exe が .bat
	よりも先に記述されているため、同じ名前のバッチファイルが存在したと
	しても、exe の方が実行されます。(明示的に拡張子を指定した場合を除く)

	その他のスクリプトに対するラッパとして使えます。スクリプト名と同じ
	名前で本プログラムをコピーして、対象のスクリプト言語のインタプリタを
	実行し、その引数には、実行したいスクリプト名を与えるよう設定します。
	これにより、あたかもスクリプト自体に実行属性を与えたかのように、直接
	実行する(のに似た)ことができます。
	Perl や Ruby などのインタプリタによっては、「ファイル冒頭の特定の記述
	までを読み飛ばす」という機能があるものがあります。一方、本プログラムは、
	「ファイルの特定の記述([eof])以降を読み飛ばす」という機能があります。
	これを組み合わせると、本プログラムの設定ファイルと、スクリプト本体を、
	ひとつのファイルに記述できます。

	これらの結果として、コマンドプロンプトがCUIのランチャになります。
	パスの通ったディレクトリに、よく使うアプリケーションをそれぞれラップ
	した本プログラムを入れておけば、どこにいてもプログラム名だけで
	実体はそれぞれどこか別のところにあるプログラムを一発で実行することが
	できます。スタートメニューや Program Files の中を探し回ったり、
	ネットワークのドライブ文字を慌てて調べたりする必要はありません。


= 動作環境 =

	WindowsNT 4.0以降 (2000/XP/Vista等)

	動作確認はWindowsXP上で行っています。


= 使用法 =

	本プログラムは、提供時は wrapexec.exe というファイル名ですが、実際に
	使用する際は、別の名前にコピーされることを想定しています。
	名前はなんでもよいですが、通常は、実行したい(ラップしたい)プログラムと
	同じ名前でコピーするのがよいかと思います。

	次にその設定ファイルを作成します(書法は後述)。コピーした本プログラムと
	同じディレクトリの、同じ名前で拡張子を .ini に置き換えたファイルが、
	設定ファイルとして使われます。

	あとはそのコピーした本プログラムを実行すれば、設定ファイルに従って
	目的のプログラムが実行されます。


= 設定ファイル(.ini) =

	実行ファイルの拡張子を .ini に置き変えたファイルを設定ファイルとして
	読み込みます。
	このファイルは、UNICODEのUTF-8で作成する必要があります。

	書式は Windows でよくある、INIファイルに似たものです。
	[section] でセクションを宣言し、それ以降にその内容を記述します。
	キーワードの大文字小文字は区別されません。
	いくつかの箇所では、${変数名}の形式で、マクロを使用できます。(後述)
	行頭および行末のスペースは無視されます。
	'#' または ';' で始まる行はコメントです。なお、行中の '#' ';' は
	コメントの開始文字としては扱われないことに注意して下さい。つまり:

	|
	|# この行はコメントです。
	|  ;  行頭のスペースは無視されるので、この行もコメントです。
	|gui = true # これはコメントとは解釈されません。
	|

	使用可能なセクションは以下の通りです。

	[option] セクション
	このセクションでは、プログラムを実行するときの様々な動作を、
	キーワード=値 の書式で記述します。「=値」は省略することもできます。
	使用可能なキーワードとその意味については後述します。

	[exec] セクション
	実行したいプログラム(のいくつかの候補)を記述します。
	マクロ(${MY_DIR}等)を使用できます。
	複数行、記述することができます。記述された順にファイルの存在チェック
	を行って、最初に見つかったものを実行します。この時、環境変数 PATH を
	参照してのサーチは行いませんので、注意して下さい。
	ここで自分自身を指定すると、無限ループになりますので注意して下さい。

	[global] セクション
	上記の [option] [exec] セクションの組は、ひとつの設定ファイルの中に
	複数個記述することができます。[option] セクションで記述した内容は、
	その [option] [exec] セクションの組についてだけ有効なので、複数の
	[option] [exec] セクションの組に共通で与えたいオプションがあるときは、
	この [global] セクションで記述することで、それ以降の全ての [option]
	セクションで個別に指定したのと同じことになります。

	[eof] セクション
	ここで設定ファイルの読み込みを終え、これより後に何が書かれていても
	無視するようにします。
	設定ファイルに、実行したいスクリプト本体を埋め込みたい時などに便利
	な場合があります。


= オプション =

	オプションには、引数に真偽値をとるものと、文字列をとるものとがあります。
	真偽値をとるオプションの場合、"true" "yes" "on" が真、"false" "no"
	"off" が偽と解釈されます。また、引数を与えなかった場合は、真として
	扱われます。
	文字列をとるオプションの場合、"=" 以降がそのまま引数として解釈され
	ます。また、引数を与えなかった場合は、空文字列として扱われます。

	例
	|
	|verbose=true		(真)
	|internal=no		(偽)
	|gui			(引数が省略されたため、真)
	|chdir=C:\work		("C:\work" という文字列)
	|

	[option] および [global] セクションで使用可能なオプションは、
	以下の通りです。

	help
	特殊なオプションです。このオプションを指定すると、簡単なヘルプを
	表示して終了します。
	本プログラムの性質上、コマンドラインから "--help" などとしても、本プロ
	グラムがヘルプを表示するようなことはなく、それはそのまま本プログラム
	から実行されるプログラムに渡されることになります。

	arg (初期値:"${ARG}")
	引数に文字列をとります。本プログラムから実行されるプログラムに
	引数をどのように渡すかを指定します。デフォルトは "${ARG}" で、これは
	本プログラムに渡された引数をそのまま渡すことを意味します。
	マクロ(${ARG}等)を使用できます。

	chdir (初期値:"")
	引数に文字列をとります。プログラムを実行する前にカレントディレクトリを
	変更したい場合に、このオプションで移りたいディレクトリを指定します。
	UNCパス(\\server\share等)も指定できますが、UNCパスに直接 chdir する
	ことはできませんので、一時的に空いているドライブ文字を割り当てた上で、
	そこに chdir します。
	マクロ(${MY_DIR}等)を使用できます。

	import_env (初期値:定義なし)
	引数に文字列をとります。このオプションを使うと、環境変数を後述の
	マクロとして使うことができます。これにより、環境変数の内容によって
	本プログラムから実行されるプログラムを切り替えたり、オプションを切り
	替えたりといったことができます。
	このオプションは複数個指定できます。

	export_env (初期値:定義なし)
	引数に文字列をとります。このオプションを使うと、後述のマクロの値を
	環境変数に設定した上で、プログラムを実行できます。環境変数は、マクロの
	名前の頭に "WRAPEXEC_" をつけた名前になります。例えばマクロ ${ARG} を
	export_env=ARG としてエクスポートすると、本プログラムへ渡された引数が
	環境変数 WRAPEXEC_ARG に設定されます。
	このオプションは複数個指定できます。

	verbose (初期値:false)
	引数に真偽値をとります。値が真の場合、内部処理の状況と状態を逐一
	表示します。設定ファイルの動作確認の際に使用すると役立つことが
	あります。

	internal (初期値:false)
	引数に真偽値をとります。値が真の場合、実行されるプログラムは
	cmd.exe の内部コマンドであるとみなされます。例えば、echo や set を
	実行したい場合、これらは cmd.exe の内部コマンドですので、ファイルとして
	echo.exe や set.exe があるわけではありません。
	本プログラムは通常、実行しようとするファイルが実際に存在することを
	確認してから実行しますので、そのままでは echo や set が実行されません。
	(プログラムが見つからない旨のエラーメッセージが出力されます)
	そのような場合、このオプションを指定すると、ファイルの存在チェックを
	省略して実行します。

	gui (初期値:false)
	引数に真偽値をとります。値が真の場合、実行されるプログラムは
	Windows の GUI のプログラムとみなされ、cmd.exe の start コマンドにより
	別ウィンドウで起動されます。また、下記の wait オプションが真でない限り
	実行されたプログラムの終了を待たず、本プログラムはすぐ終了します。

	wait (初期値:false)
	引数に真偽値をとります。本オプションは、前述のオプション gui が真の
	場合のみ意味を持ちます。値が真の場合、本プログラムから実行された
	プログラムが終了するまで、そのまま待機します。(通常、本プログラムは
	すぐ終了します)

	maximize (初期値:false)
	引数に真偽値をとります。本オプションは、前述のオプション gui が真の
	場合のみ意味を持ちます。値が真の場合、ウィンドウを最大化して起動する
	よう、実行されるプログラムに指示します。
	これを指定すると、minimize が false になります。

	minimize (初期値:false)
	引数に真偽値をとります。本オプションは、前述のオプション gui が真の
	場合のみ意味を持ちます。値が真の場合、ウィンドウを最小化して起動する
	よう、実行されるプログラムに指示します。
	これを指定すると、maximize が false になります。


= マクロ =

	設定ファイル中のいくつかの場所では、${名称} の形式で、マクロ展開を
	使用することができます。
	「${」という文字列そのものを表すには、「$${」と記述します。
	「${名称}」の他、「$(名称)」「$[名称]」の書式も使用できますが、
	「$名称」の書式は使用できません。必ず括弧で括る必要があります。
	マクロ展開は一度だけ行われ、展開された文字列が再びマクロ展開される
	ことはありません。

	標準で使用できるマクロは以下の通りです。

	ARG
	本プログラムに与えられたコマンドライン引数。(プログラム名以降の部分)
	プログラム名と引数の間のスペースも含まれることに注意して下さい。
	例えば、"wrapexec.exe FooBarBaz" として実行した場合、${ARG} は
	" FooBarBaz" に展開されます。
	コマンドラインで与えられた、スペースの個数や特殊記号、UNICODE文字等も
	そのまま忠実に再現して同じものが展開されます。

	CLIPBOARD
	プログラム実行時のクリップボードの値。
	クリップボードの内容がテキスト以外だった場合は、空文字列となります。
	改行やタブ文字などのホワイトスペース文字は、スペースに置換されます。

	MY_EXENAME
	自分自身 (wrapexec.exe) のフルパスファイル名。
	例 : D:\somewhere\wrapexec.exe

	MY_ININAME
	設定ファイルのフルパスファイル名。
	例 : D:\somewhere\wrapexec.ini

	MY_BASENAME
	自分自身 (wrapexec.exe) のベース名(ドライブ名、パス名、拡張子を除いた
	名前)。
	例 : wrapexec

	MY_DIR (別名 : MY)
	自分自身 (wrapexec.exe) のパス名。(ドライブ名および末尾の'\'を含む)
	例 : D:\somewhere\

	MY_DRIVE
	自分自身 (wrapexec.exe) のあるドライブ名。
	例 : D:

	SYS_NAME
	コンピュータ名。
	例 : SOMEONESPC

	SYS_ROOT
	システムのルートディレクトリ。
	例 : C:\WINDOWS\

	SYS_DIR (別名 : SYS)
	システムディレクトリ。
	例 : C:\WINDOWS\system32\

	SYS_DRIVE
	システムドライブ。
	例 : C:

	USER_NAME
	ユーザ名。
	例 : someone

	USER_DIR (別名 : USER)
	ユーザのプロファイルのディレクトリ。
	例 : C:\Documents and Settings\someone\

	USER_DRIVE
	ユーザのプロファイルのあるドライブ。
	例 : C:

	USER_DOC
	ユーザのマイドキュメントのディレクトリ。
	例 : C:\Documents and Settings\someone\My Documents\

	USER_DESKTOP
	ユーザのデスクトップのディレクトリ。
	例 : C:\Documents and Settings\someone\デスクトップ\

	ALL_USER_DIR (別名 : ALL_USER)
	共通のプロファイルのディレクトリ。
	例 : C:\Documents and Settings\All Users\

	ALL_USER_DRIVE
	共通のプロファイルのあるドライブ。
	例 : C:

	ALL_USER_DOC
	共有ドキュメントのディレクトリ。
	例 : C:\Documents and Settings\All Users\Documents\

	ALL_USER_DESKTOP
	共通のデスクトップのディレクトリ。
	例 : C:\Documents and Settings\All Users\デスクトップ\

	PROGRAM_DIR (別名 : PROGRAM)
	プログラムフォルダのディレクトリ。
	例 : C:\Program Files\

	PROGRAM_DRIVE
	プログラムフォルダのあるドライブ。
	例 : C:

	TMP_DIR (別名 : TMP)
	テンポラリディレクトリ。
	例 : C:\DOCUME~1\SOMEONE\LOCALS~1\Temp\

	TMP_DRIVE
	テンポラリディレクトリのあるドライブ。
	例 : C:

	上記の他、オプション import_env で、任意の環境変数をマクロ展開に使用
	することができます。

	個々の環境での具体的な値は、オプション verbose を真と設定すると
	確認することができます。


= 設定ファイル記述例 =

	Perlスクリプト theScript.pl を実行する例
	(本プログラムと同じディレクトリに theScript.pl が存在するものとする)
	|
	|[option]
	|arg="${MY_DIR}theScript.pl"${ARG}
	|[exec]
	|c:\Perl\bin\perl.exe
	|

	設定ファイルの後半に書かれた Rubyスクリプトを実行する例
	|
	|[option]
	|arg=-x "${MY_ININAME}"${ARG}
	|[exec]
	|c:\Ruby\bin\ruby.exe
	|[eof]
	|#!ruby
	|p "Hello World!"
	|

	Program Files の奥底にある MyFavoriteEditor.exe を最大化して実行する例
	|
	|[option]
	|gui
	|maximize
	|[exec]
	|${PROGRAM}folder\to\program\MyFavoriteEditor.exe
	|

	どこかにある gypsy.exe を実行する例
	|
	|[exec]
	|${SYS}gypsy.exe
	|${PROGRAM}gypsy\gypsy.exe
	|c:\somewhere\gypsy.exe
	|c:\anotherwhere\gypsy.exe
	|\\far\shere\gypsy.exe
	|

	レジストリをクリアしてから 目的のプログラムを実行する例
	|
	|[option]
	|arg=${MY_DIR}initialize.reg
	|[exec]
	|${SYS_ROOT}regedit.exe
	|[exec]
	|target.exe
	|

	名前順でソートする dir コマンドの例
	|
	|[option]
	|internal
	|arg=/on${ARG}
	|[exec]
	|dir
	|


= 使用上の注意 =

	本プログラムはなるべく意図した通りに動作するよう心がけて作成していま
	すが、設定ファイルの誤りやその他の原因で、意図せぬプログラムを意図せぬ
	オプションで実行してしまうことが、絶対にないとはいえません。必ず充分な
	動作確認を行ったうえで使用してください。

	本プログラムはその目的上、設定ファイルを書き換えることにより多様な動作
	をさせられるため、その取り扱いには注意して下さい。万一、悪意ある第三者に
	設定ファイルを改竄された場合の影響は計り知れません。


= 欠点 =

	普通にプログラムを実行するより、ややメモリを多く消費します。
	本プログラム および コマンドを実行するために使用している cmd.exe が
	それぞれメモリを消費するためです。


= 既知のバグおよび今後の課題 =

	SourceForge.jp 内の チケットシステムを参照してください。(ただしまだ作成中)


= 謝辞 =

	記載の社名、製品名は各社の商標または登録商標です。

	このプログラムは、Borland C++ でコンパイルされています。

	このプログラムは、UPX で圧縮されています。


= 権利 =

	Copyright (c) 2009 by opa
	All rights reserved.

	ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の
	条件を満たす場合に限り、再頒布および使用が許可されます。

	・ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、
	 および下記免責条項を含めること。
	・バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、
	 上記の著作権表示、本条件一覧、および下記免責条項を含めること。
	・書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝
	 または販売促進に、作者(おぱ)の名前またはコントリビューターの名前を
	 使用してはならない。

	本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」
	提供されており、明示黙示を問わず、商業的な使用可能性、および特定の目的に
	対する適合性に関する暗黙の保証も含め、またそれに限定されない、いかなる
	保証もありません。著作権者もコントリビューターも、事由のいかんを問わず、
	損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか厳格責任で
	あるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生
	する可能性を知らされていたとしても、本ソフトウェアの使用によって発生した
	(代替品または代用サービスの調達、使用の喪失、データの喪失、利益の喪失、
	業務の中断も含め、またそれに限定されない)直接損害、間接損害、偶発的な
	損害、特別損害、懲罰的損害、または結果損害について、一切責任を負わない
	ものとします。