Batch file to VBScript file (11) at 1999.Sep.17 3.9 共通ルーチンが使えないタコな仕様  VBScriptでもっと巨大なもんを作ってみました。  だけど、本気で面倒くさいんでやんの。DOSのバッチとか、unixのshell script  とか、VAX/VMSのCommand procedureとかってのは、とにかくコマンドラインから  入力しているモンをほぼそのままファイルにすればOKOKだったっちゅーのに、何で  このVBSとやらはごちゃごちゃと宣言やら定義やらをしないとだめなの?  「ほほほ。それはMicrosoft製だからだよ。Q.E.D.(証明終わり)」  …まぁしょうがないですぅ(X_X)。  で、WSHを使う上で困ったこと。それは「共通のサブルーチンが使えない」です。 #正確にはサブルーチンからの値の戻りに制限がありすぎ。ってことだけど  10本のVBSで同じような処理が必要である場合、同じサブルーチンをコピーして  使うのが嬉しいか、それともサブルーチンだけを独立して別ファイルにし、10本の  VBSはどれもその1つだけのファイルを参照して動く方が嬉しいか。ということ。  何も考えたくないというスカな人(*1)なら前者を選ぶでしょう。だけどファイル  サイズは無駄だし(何せ同じサブルーチンがコピーされてるだけだもの)、その  サブルーチンに問題があると判明したら10本全部のVBSを書き換えなくてはなりません。  これは非常に馬鹿げたことですね。Windowsに山ほど付属する、*.DLLとか*.VxD、  *.OCX何てのは突き詰めると全てサブルーチン集だ。と言えるってのに、WSHはその手の  機能を考慮してません。情けないとゆーか馬鹿じゃねぇかとか思うのですが。  (え?スクリプティング・コンポーネント?いや、その。MSの、常に事態をややこしく   する方向にしか発展しない。という方向性にはどーしても共感を覚えないとゆーか、   老人はいたわって欲しいとか「老兵は死なず、ただ消え行くのみ」とゆーか。   思うのですが……。あぅ。負け犬の遠吠えは無様だって?[しくしく])  それはともかく。  (*1)あるいは、込み込みで判断して有利・不利を判断した結果ってのもありですがね  ちなみに上で引き合いに出したunixのshellとかVAXのCommand procedureとかはきっちり  そーゆーこと(環境変数を媒介としてスクリプト間で値を引き渡すこと)ができます。  何とバッチだって環境変数やエラーレベルを介せば複数バッチ間の連携は取れたの  ですがね(ただ、DOSの環境変数領域って直ぐに足りなくなるんで、あたしとしては  可能な限り使わないようにしてますが)。  まぁWSHでだって環境変数は使えるんだし?やってみましょう。 Option Explicit Dim wsh: Set wsh = Wscript.CreateObject("Wscript.Shell") Dim wev: Set wev = wsh.Environment Call msgbox(wev("path")) ' 変更前 wev("path") = "なし" Call msgbox(wev("path")) ' 変更後  見事書き換わったって?残念でした。も一度実行してみても全く同じ実行結果が  得られます。つまりVBSの実行が終わればどんなにそのVBS内部で環境変数を書き換え  ても元に戻るってことですな。  ちなみにDOS窓でやっても同じだから、試してみましょ。  C:\VBS> cscript //nologo tst.vbs  つまりバッチの時には使えた、環境変数を介して複数のVBS間での変数の受け渡しは  できないということ。環境変数に限ってはバッチ未満の機能しかWSHにはない。  という訳です(こんなんでバッチの代わりになるだと?いやはや>M$)。  でもこれは実はDOSというか、Windowsの仕組み上、実は当然なのですわ。子プロセスが  起動する時に親プロセスの環境を引き渡すことはできるが、子から親のプロセスを  いじる手段は標準ではない。もちろん、バッチの場合、子プロセスから親プロセスの  環境変数をいじることは可能でした。「可能」ってったって、MSの保証が何もない  DOSの内部データをいじって実現してた訳でして、当然のごとく、DOSのバージョンが  上がるとその手のプログラムは使えなくなりました(-_-)。  後、子プロセスには親プロセスの環境変数のコピーが渡されるけど、余裕分までは  渡されないってこともあった気がします。つまり、親が4096バイトの環境変数領域を  確保し、そのうち1024バイトしか実際には使用してない状態で子を起動すると、  子には1024バイト分の環境変数領域しか渡されないので、子側で1025バイト使おうと  してもだめだったと思います(違ったらごめん)。  でもバッチでは環境変数が書き換えられたぞ?と思ったあなた。それは子プロセスが  動いていなかったからです。  バッチを解釈して実行していたのはCOMMAND.COMです。COMMAND.COMという単一の  プロセス内で複数のバッチが動いても問題はなかった。ということでしかありません。  実際、バッチから他のバッチを呼ぶにあたり、Callコマンド(これはバッチの機能)を  使えば、呼び出したバッチで環境変数を書き換えると戻った元のバッチからは書き  換えた値が参照できますが、COMMAND/Cで新しく子プロセスを作って他のバッチを呼ぶと、  戻ってきた時には環境変数は元に戻っていたはずです。  バッチではこの性質をうまく使うと、おもしろいバッチが書けたのです。が、  今はWSHのVBScriptのことを話していますので話題を元に戻します。  ではバッチ時代に使っていたもう一つの方法。それはエラーレベルです。これが  辛うじて使えます。  試してみましょう。ちなみにこれは、VBSから別のVBSを呼び出し、呼び出し側で  環境変数を変更してからもとのVBSに戻ってもやっぱりだめだ。というサンプルにも  なってます。  main.vbs: Option Explicit Dim wsh: Set wsh = Wscript.CreateObject("Wscript.Shell") Dim wev: Set wev = wsh.Environment Dim er wev("t") = "初期値" Call msgbox(wev("t"),,"main-before") er = wsh.Run("sub.vbs",, True) Call msgbox(wev("t"),,"main-after: ret=" & er)  sub.vbs: Option Explicit Dim wsh: Set wsh = Wscript.CreateObject("Wscript.Shell") Dim wev: Set wev = wsh.Environment Call msgbox(wev("t"),,"sub-before") wev("t") = "最終痴" Call msgbox(wev("t"),,"sub-after") Call Wscript.Quit(7)  …字が違うって?あれ?文句はMS-IME98に言ってね。細かいことを気にしてたら  人間、長生きできないんだってばさ(^^;;;  ところで、エラーレベルは幾つまで可能なのでしょうか。これはDOSを知っている  人なら推測できますが、0〜255までです。  MS-DOSのプログラム終了コードって、こうですから。 mov ah, 4Ch ; プログラム終了のファンクションコード mov al, 0 ; エラーコード int 21h  ま、Win32になってAPIでは32 bitで戻り値が返せるように仕様上はなってますが、  VBSで試すと、Call Wscript.Quit(256)で、エラーレベルが0になっちゃいますからねぇ。  所詮Windows9xってDOSですからそんなもんでしょう。 #あう。予定より長くなったぞ。ということで次 (EOF)