HTAからWScriptへアクセスしてみた2007年06月05日 20時15分12秒

とりあえずのテスト

6/1のエントリで紹介した、「Windows Script Programming」さんのWindowsアプリからWScript.exeのWScriptオブジェクトを利用するをとりあえず試してみた。

元々頭の中にあったのが「WScriptオブジェクトをHTAに渡せば、HTAからグローバルメンバにアクセスできるぜ。へへへ」てなことだったのだが、なんかイマイチうまくいかなかった。

よくよく考えてみると、単体のJSファイルでも

WScript == this
falseになるので無理だったのだが、それがわかるまで結構ハマった。

なので、IEを経由させるのはWScriptではなくthisにするようにしてみた。

他にも型のチェックとかで元のコードを単純に移行しても動かなかったのと、もらったWScriptからWshShellを作成してPopup叩いてもイマイチ面白くないので、HTAからWScript.EchoとWScript.StdIn.ReadLineを試してみるようにした。

で、作ってみたコード

まずjs側。名前を「wsh.js」とする。

function echo(s) {
	WScript.Echo( s );
}

function readln(msg) {
	if(msg) WScript.StdOut.Write(msg);
	return WScript.StdIn.ReadLine();
}
// 終了待ち合わせフラグ
var quit = false;

var sh = new ActiveXObject("WScript.Shell");
var shell = new ActiveXObject("Shell.Application"), ie;

for(var col = new Enumerator( shell.Windows() ); ! col.atEnd(); col.moveNext()) {
	if( col.item().hWnd == WScript.Arguments.Item(0) ) {
		ie = col.item();
		break;
	}
}

ie.PutProperty( "WScript", this );
// HTAからquitにtrueがセットされるまで待ち合わせ
while( ! quit ) {
	WScript.Sleep(1000);
}

sh.Popup( "completed." );

そんでこっちがHTA側。名前はなんでもいいけど「test.hta」とかにしておく。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>test</title>
</head>
<body>

</body>
<script>
var ie;
window.onbeforeunload = function() {
	ie.Quit();
}
setTimeout( function() {
	ie = new ActiveXObject("InternetExplorer.Application");
	var shell = new ActiveXObject("WScript.Shell");

	var ws;
	shell.Run( [ "cscript wsh.js ", ie.hWnd ].join("") );
	for(var k = 1; k < 11; k++) {
		ws = ie.GetProperty("WScript");
		// wsh.jsからプロパティがセットされるとundefinedではなくなる。型は見なくてもOK(のハズ)
		if( typeof( ws ) != "undefined" ) break;
		shell.Run( "ping localhost -n 2", 0, true );
	}
	for(var i = 0; i < 10; i++) {
		ws.echo( new Date() );
		ws.WScript.Sleep( 1000 );
	}
	
	alert( ws.readln("なんか入力すれ。 > ") );
	
	ws.quit = true;
	window.close();
}, 0 );
</script>
</html>

IEに設定するプロパティ名が「WScript」になっているが、wsh.jsでセットしているオブジェクトはWScriptではなく、グローバルコードでの「this」になるので注意。

で、test.htaとwsh.jsを同じところに配置してtest.htaを起動すると、

  1. コンソール(cscript.exe)が起動して、1秒間隔で10回時間を表示する
  2. コンソールで入力を求められる
  3. HTA側でコンソールで入力された文字をalertして終了
  4. コンソール側もメッセージを表示して終了
となる。

簡単なライブラリ化をしてjsからHTAをダイアログのように使うのも試してみたので次のエントリで。

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://dara-j.asablo.jp/blog/2007/06/05/1557869/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。