LoginSignup
2
2

More than 3 years have passed since last update.

令和になってもなお JScript で VBScript の InputBox を使う

Last updated at Posted at 2019-10-03

以前、このテーマについて以下のような記事を書いた。

今更だが JScript で VBScript の Inputbox を使う - Qiita
https://qiita.com/itasnasal/items/1747f9bcf6859093b7fe

ここでは wsc (Widows Script Component) を使う、という奇矯な方法に辿り着いた。
しかし。
結局原因は不明なままだが、2回呼び出すと2回目がきちんと動かなかったりとか安定しない。
元々半ば冗談で試した手法で「できるじゃんwww」的なところが大きかった。

「少なくとも、全く同じものはWEBではいまのところ見つけられてない。」に尽きる。

そして久しぶりにこの問題をもう一度考えてみた。

「どうにかして JScript から VBScript を動かして、結果を取得する」

どうすればいいか。

ここで身も蓋もない原点に戻ってきた。

「スクリプトなんだからスクリプト・ファイル作って実行すればいいじゃん。」

というわけで書いたのがこれである。

・InputBox を実行して結果を標準出力に吐くVBScriptファイルを生成する。
・これを WshShell.exec() で実行して、標準出力の内容を取ってくる。

// magic spell for WSH ///////////////////////////////////////////////////////
if(typeof console==="undefined")  console={log: function(s){WScript.Echo(s)}};
if(typeof process==="undefined"){ process={exit:function(e){WScript.Quit(e)}};
var v=process.argv=[];v.push(WScript.FullName);v.push(WScript.ScriptFullName);
var n=WScript.Arguments.Unnamed;for(var i=0;i<n.length;i++)v.push(n.item(i))};
//////////////////////////////////////////////////////////////////////////////

// require('vbFunctions');  // 超原始的に JScript から VBScript の関数を実行する。
initVbsFunction();

var result = vbsMsgBox( 'テストです。', 3+32, 'MagBoxTest' );
console.log( result );

var result = vbsInputBox( 'テストです。', 'InputBoxTest', 'デフォルト値', 3000, 1500 );
console.log( result );

process.exit()


function initVbsFunction() {
//--------------------------------------------------------------------------//

//////////////////////////////////////////////////////////////////////////////
// 超原始的に JScript から VBScript の関数を実行する。
// 現在は以下の2つ。
//
// vbsInputBox( prompt, title, dflt, xpos, ypos, helpfile, context ) 
// vbsMsgBox( prompt, buttons, title, helpfile, context )
// 
// おまけ:とりあえずこれも出しとく。
// vbsFunction( funcName, args ) 

var fso = fso || new ActiveXObject("Scripting.FileSystemObject");
var WshShell = WshShell|| new ActiveXObject("WScript.Shell");

// 超原始的に JScript から VBScript の InputBox を実行する。
vbsInputBox = function( prompt, title, dflt, xpos, ypos, helpfile, context ) {
    return vbsFunction( 'InputBox', arguments );
}

// 超原始的に JScript から VBScript の MsgBox を実行する。
vbsMsgBox = function( prompt, buttons, title, helpfile, context ) {
    return vbsFunction( 'MsgBox', arguments );
}

// 超原始的に JScript から VBScript の関数を実行するための共通ルーチン
vbsFunction = function( funcName, args ) {

    var vbsPath = genTempNameEx( 'Dummy_', '.vbs' );
    var param = [];
    for (var i = 0; i < args.length; ++i) param[i] = ( '\"'+args[i]+'\"' );

    var vbs = 'WScript.Echo ' + funcName + '( '+ param.join(', ') +  ' )';

    text2file( vbs, vbsPath );

    var sce = WScript.FullName.replace(/Wscript/i, "cscript") + " //nologo ";
    var oExec = WshShell.exec(  sce + vbsPath );
    var result = oExec.StdOut.ReadAll().replace(/\r\n$/,"");
    fso.DeleteFile( vbsPath );

    return result

}
// %TEMP% 内に一時ファイル名を生成
function genTempNameEx( prifix, postfix ) { // 一時名前の生成
    prifix  = prifix  || '';
    postfix = postfix || '';
    var tempPath = fso.BuildPath( fso.GetSpecialFolder(2), prifix + fso.GetTempName() + postfix );
    // fso.GetTempName() を使ってみる。
    if( fso.FileExists( tempPath ) || fso.FolderExists( tempPath ) ) throw new Error( '一時ファイル名の生成に失敗しました。' );
    return tempPath;
}

// 指定ファイルを全読みしてテキストで返す。
function file2text( file ) {
    if( ! fso.FileExists( file ) ) return null;
    var f = fso.OpenTextFile( file, 1 );    //  iomode 1:ForReading
    var r = "";
    if( ! f.AtEndOfStream ) r = f.ReadAll();
    f.close();
    return r;
}

// 指定テキストをファイルに保存する。
function text2file( text, file ) {
    var f = fso.CreateTextFile( file, true );
    f.Write(text);
    f.close();
    return;
}

//  module.exports = {};
//--------------------------------------------------------------------------//

}

Script Control使って「別の言語のコードを押し込んで使う」んじゃなく
普通に「別の言語のスクリプトファイルを書いて実行する」というシンプルな方法。

最初すごくあほらしいと自分では思ったけれども、1ファイルに収まるし、使っている仕組みも既知のシンプルなもので、内部の動きに wsc のような不明さ謎さもない。

奇矯な方法よりも、いろいろシンプルであることが大事だよなあ。と改めて思いました。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2