2018-07-24T01:47:51Z

WSH(JScript)でコードを書いてみる

WSHでコードを書くための基礎知識とサンプルの実行例です。

Hello World

お決まりの実行テストです。(Windows環境であれば、特別な環境構築は不要です)

  1. 下記の1行のコードをテキストファイルにjseの拡張子で保存する
  2. 作成したファイルをダブルクリックして実行する
  3. 参考画像のダイアログが出現すれば成功です
WScript.Echo('Hello World.');

enter image description here

事前知識

WSH関連の基礎知識です。

js/jseファイル

jsは、JavaScriptのファイル拡張子です。jseは、JScriptのファイル拡張子です。

Windowsの標準では、wscriptが関連付けされており、ダブルクリックで実行できます。

wsfファイル

外部スクリプトをロードして実行できるWSHのファイル形式です。

WSHでは、「.js」「.jse」「.wsf」などの拡張子を使用できます。ですが、実行ファイルを複数ファイルに分割した場合、「.wsf」を使用することが無難です。(eval関数を使用することで他の方法でも実現できますが、おすすめできる方法ではありません)

wsfファイル内にスクリプトを直接書き込む場合、<![CDATA[ ... ]]>(CDATAセクション)を記述してスクリプト要素で使用する文字が XML の予約文字と見なされないようにします。CDATAセクションを使用する場合は、必ず<?XML?>宣言も使用します。

※CDATAを使用しない場合、if分の<(小なり括弧)が原因で動作しないことがあります

<?xml version="1.0" standalone="yes" ?>
<package>
  <job>
    <script language="JavaScript"><![CDATA[
WScript.Echo('Hello World.');
    ]]></script>
  </job>
</package>

polyfill

WSHは、IE8環境で動作します。IE11がインストールされている場合でもスクリプトはIE8の環境で動作します。そのため、JavaScriptの標準規格からかなり遅れた仕様で動作します。最新のJavaScript規格でないため、様々な問題が発生します。

例として、下記関数が存在しません。

  • Object.keys
  • Array.isArray
  • Array.prototype.indexOf
  • Date.now
  • String.prototype.trim
  • Function.prototype.bind

WSHを最新環境に近づけるため、未定義の関数を追加しするのがpolyfillです。

様々なpolyfillがありますが、最低限ECMAScript 5環境でWSHを実行するために、es5-shim.jsの導入をすすめします。

※WSHには、windowやdocumentのグローバル変数が存在しません。そのため、そのままではpolyfillを導入できないことがよくあります。

JSON

WSHは、JavaScriptですが標準のJSONクラスが存在しません。そのため、JSON.stringify()やJSON.parse()を使用できません。JSON使用したい場合、polyfillを導入する必要があります。詳細は、リンク先を参照してください。

デバッグ

WSHのコードデバッグ方法です。詳細は、リンク先を参照してください。

クラス表現

JavaScriptは、ECMAScript 6でclassの予約語が使用可能になりましたが、WSHではclassの予約語を使用できません。これは、polyfillでも対処できません。ですが、JavaScriptでは、ECMAScript 6以前からクラス表現を擬似的に再現できます。クラス表現方法は、各々の使いやすい方法を選択すると良いでしょう。選択肢の一例として、筆者の実現方法は下記リンク先の通りです。

他筆者の自作ライブラリ(宣伝)

補足

ファイルの文字コード

wsfファイルの文字コードは、BOM付きUTF-16推奨を推奨します。
Shift_JISも使用可能ですが、あまりおすすめできません。

UTF-8は、使用しないほうが良いです。理由として、UTF-8のコードとした場合、筆者の環境でエラーとなり実行できませんでした。(ErrorUtility.jsやConsole.Animation.jsをUTF-8でコーディングするとコメント以外全角文字はないはずだが、実行時にエラーなり、動作しなかった)

ロゴの非表示

以下のコードを1回実行するとそれ以降、cscriptの実行時にロゴを非表示にできる。

cscript //Nologo //S

元に戻す

cscript //Logo //S

ロゴの例(実行直後にコマンドプロンプトで表示される文字列)

Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

ファイル配置

参考までに筆者の開発環境のファイル配置例を以下に示します。

./common/FileUtility.js
./lib/es5-shim.min.js
./lib/json3.min.js
./test/test.wsf
フォルダ名 説明
. ルート
./common 自作ライブラリ
./lib 外部ライブラリ
./test プロジェクト毎のメインフォルダ

上記ファイル配置の場合、wsfファイルの外部スクリプト参照は以下のようになります。

    <script language="JavaScript" src="../lib/es5-shim.min.js"/>
    <script language="JavaScript" src="../common/FileUtility.js"/>

スクリプト実行

サンプルのスクリプトの実行例です。

環境準備

以下のようにファイルを配置する。下記のサンプル実行用の配置です。
フォルダ格納例

※下記のサンプルは、文字コードをUTF-16で保存してください。

サンプル:ファイル一覧の表示

<?xml version="1.0" encoding="UTF-16" standalone="yes" ?>
<package>
  <job id="main">
    <?job error="false" debug="false" ?>
    <script language="JavaScript" src="es5-shim.min.js"/>
    <script language="JavaScript" src="json3.min.js"/>
    <script language="JavaScript" src="FileUtility.js"/>
    <script language="JavaScript"><![CDATA[
(function() {
  "use strict";
  
  function main() {
    // フォルダ直下のファイルのフルパスを表示する
    FileUtility.findFile(function(fullpath) {
      WScript.Echo(fullpath);
    }, '.');
  }
  
  main();
})();
    ]]></script>
  </job>
</package>

enter image description here

サンプル:JSONファイルの読み書き

<?xml version="1.0" encoding="UTF-16" standalone="yes" ?>
<package>
  <job id="main">
    <?job error="false" debug="false" ?>
    <script language="JavaScript" src="es5-shim.min.js"/>
    <script language="JavaScript" src="json3.min.js"/>
    <script language="JavaScript" src="FileUtility.js"/>
    <script language="JavaScript"><![CDATA[
(function() {
  "use strict";
  
  function main() {
    // JSONを保存
    var json = {"a": "abc", "b": 123};
    FileUtility.storeJSON(json, "./test.json", true);
    
    // JSONを読込
    var test = FileUtility.loadJSON("./test.json");
    
    WScript.Echo(test.a); // 「abc」を表示する
    WScript.Echo(test.b); // 「123」を表示する
  }
  
  main();
})();
    ]]></script>
  </job>
</package>

enter image description here

その他

 コメントを書く