▼ HTA
▼ IE11
ドキュメントモードは IE10 で
<meta http-equiv="x-ua-compatible" content="ie=10" />
JavaScript だけで処理できる場合は、ie="edge" で最新のドキュメントモードで動作します。しかし、VBScript を使う場合は ie="10" でないと動作してくれないので注意が必要です。(省略するとドキュメントモードは 5 のようです)
IE11 でも、信頼するサイトに http://localhost を登録して、レベルのカスタマイズで『スクリプトを実行しても安全だとマークされていないActiveX コントロールの初期化とスクリプトの実行』を『有効』にすれば .hta を .html に変更して動作可能です。
SCRIPT 要素の language="VBScript"
<script language="VBScript">
</script>
主体が JavaScript の場合は、VBScript を記述する場所は language="VBScript" を記述する必要があります。但し、ページ上で最初に現れるスクリプトは JavaScript である必要があります。先に、VBScript が定義されていると VBScript がデフォルトの言語になってしまいます。( 一般要素にインラインのイベントで VBScript を書く場合も language="VBScript" が必要です )
WMI を使用する為に GetObject が必要です
この為に VBScript が必要になる場合と、JavaScript では Windows で用意されたオブジェクトからの値をうまく取得できない場合もあるので、VBScript を要所に設置する必要があります。このサンプルでは、GetObject で WMI のレジストリ処理を可能にする為に使っているのと、メソッドに変数を渡して戻ってくる値を使えるようにする為に使用しています。
▼ レジストリのエントリ名の一覧を JavaScript の配列に変換する為の流れ
JavaScript から呼び出し => VBScript で処理 => VBArray を引数で JavaScript に引き渡す => JavaScript の配列にする
VBArray の扱い
Microsoft のドキュメントではピンと来ないのですが、結果的に オブジェクトとのやり取りする場合、配列はほぼ全て safeArray だと思われます。そして、JavaScript 内で受け取った時点で既に、VBArray のようなので、そのまま toArray() で配列化します。( VBScript が JavaScript の関数に引数として渡しても、JavaScript 側では VBArray のようです )
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=10" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="hta.js"></script>
<script language="VBScript">
' *****************************************
' VBScript を使用するには、
' x-ua-compatible で、ie=10 です
' *****************************************
' オブジェクトの取得
Set objRegistry = GetObject("Winmgmts:root\default:StdRegProv")
' *****************************************
' VBScript の関数
' *****************************************
Function GetObjectArray(RegPath)
Dim aNames,aTypes
on error resume next
WMIRet = objRegistry.EnumValues( &H80000002, RegPath, aNames, aTypes )
if Err.Number <> 0 then
alert( Err.Description )
GetObjectArray = False
Exit Function
end if
if WMIRet <> 0 then
alert( "処理に失敗しました" )
GetObjectArray = False
Exit Function
end if
on error goto 0
if IsNull( aNames ) then
alert( "データがありません" )
GetObjectArray = False
Exit Function
end if
Call setObjRegistry( aNames )
GetObjectArray = True
End Function
</script>
<script>
// ウインドウの位置とサイズ
centerWindow( 1100, 600 );
// テーブルの行作成用
var row_data = "";
// Microsoft Windows 標準オブジェクト作成
var WshShell = newObject("WScript.Shell");
var objShell = newObject("Shell.Application");
$(function(){
// レジストリキーの値一覧
$("#act").on("click", function(){
if ( GetObjectArray( $("#regkey").val() ) == 0 ) {
return;
}
// テーブル表示リセット
$("#tbl .row_data").remove();
// 配列より一覧作成
var len = regArray.length;
for( i = 0; i < len; i++ ) {
row_data = $("<tr></tr>")
.addClass("row_data")
.appendTo( "#tbl" );
$("<td></td>")
.text(regArray[i])
.appendTo( row_data );
}
});
// 実行
$("#run").on("click", function(){
WshShell.Run("ms-settings:windowsupdate");
});
// 管理者実行
$("#admin_run").on("click", function(){
objShell.ShellExecute("cmd.exe", "", "", "runas", 1);
});
// 再表示
$("#view").on("click", function(){
location.reload(true);
});
// IE のドキュメントモードを表示
$("<div></div>")
.text( document.documentMode )
.css( { "float" : "right", "color": "#808080", "font-size": "8px" } )
.insertBefore( $("p").eq(0) );
// 表示位置微調整
$( ".btn,#regkey" ).css({
"margin-top": "-4px"
});
});
</script>
<style>
/* ブロックを左右に表示 */
.ttl {
display: inline-block;
width: 300px;
vertical-align: top;
}
.entry {
display: inline-block;
}
.line {
margin-bottom: 0;
}
#head {
padding: 16px;
}
/* DIV を Window 下部にフィット */
html,body {
height: 100%;
}
body {
margin: 0;
}
#head {
padding: 16px;
width: 100%;
height: 180px;
background-color: #e0e0e0;
}
#extend {
padding: 4px 16px;
display: block;
margin-left: auto;
margin-right: auto;
width: calc( 100% - 3px );
height: calc( 100% - 180px - 2px );
border: solid 2px #c0c0c0;
overflow: scroll;
}
/* テーブルのカーソル用 */
.row_data td, .row_data th {
cursor: default!important;
white-space: pre;
}
</style>
</head>
<body>
<div id="head">
<p class="ttl">
HKEY_LOCAL_MACHINE レジストリキー
</p>
<p class="entry">
<input
id="regkey"
type="text"
style="width:600px;"
value="SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers">
</p>
<p class="line"></p>
<p class="ttl">
</p>
<p class="entry">
<input
id="act"
class="ml-4 btn btn-outline-primary"
type="button"
value="一覧表示">
<input
id="run"
class="ml-4 btn btn-outline-primary"
type="button"
value="実行">
<input
id="admin_run"
class="ml-4 btn btn-outline-primary"
type="button"
value="管理者実行">
<input
class="ml-4 btn btn-info btn-sm"
id="view"
type="button"
value="再表示">
</p>
<p class="line"></p>
<h4 class="text-danger"></h4>
</div>
<div id="extend">
<table class="table table-hover">
<tbody id="tbl">
</tbody>
</table>
<br>
</div>
</body>
</html>
※ 画面上右端に、IE のドキュメントモードを表示するようにしました
// IE のドキュメントモードを表示
$("<div></div>")
.text( document.documentMode )
.css( { "float" : "right", "color": "#808080", "font-size": "8px" } )
.insertBefore( $("p").eq(0) );
サンプルとして、外部アプリケーションの二つの実行方法を記述しています。( Shell.Application では管理者権限での実行が可能です )
hta.js
newObject 関数は、VBScript の CreateObject ライクに使えるようにしたので、取得に失敗すると戻り値は null が返ります。
// *************************************
// ウインドウの位置とサイズ
// *************************************
function baseWindow( x, y, w, h ) {
top.moveTo( x, y );
top.resizeTo( w, h );
}
// *************************************
// デスクトップ中央
// *************************************
function centerWindow( w, h ) {
// ウインドウの位置とサイズ
top.resizeTo( w, h );
top.moveTo((screen.width-w)/2, (screen.height-h)/2 )
}
// *************************************
// CreateObject
// *************************************
function newObject( className ) {
var obj;
try {
obj = new ActiveXObject( className );
}
catch (e) {
obj = null;
}
return obj;
}
// *************************************
// VB より呼びだされる
// VBArray を JS 配列に変換する関数
// *************************************
function setObjRegistry( vbArray ) {
window.regArray = vbArray.toArray()
window.regArray.sort();
}
※ window.regArray は、JavaScript でグローバル変数(と同等?)の保存をする為の手法です。
※ 2列以上のデータセット個別の列でソートするには、ADODB.Recordset を使用します。
関連する記事
HTA + Basp21 + jQuery + twitter-bootstrap(4.1.1) でメール受信ツール