[追記]
フレームワークの内容が一部変更されている為、最新は wes そのものを参照してください。
1998 年に WSH (Windows Script Host) が登場してから 20 年以上が経ちます。
標準で搭載されているスクリプト実行環境でありながら、仕様の古さから記述が冗長になりがちです。
スクリプトエンジンを Chakra に変更できことが知られて多少注目されたことがありましたが、実行環境や開発環境としては根本的に変わっておらず、徐々に忘れ去られていく技術になっています。
wes (Windows EcmaScript host) は WSH の JScript を効率的に開発するためのフレームワークです。
wes の特徴
- スクリプトエンジンを Chakra に変更して ES2015+ の仕様で記述できます
- モジュールシステムが従来より開発効率を高めます
- ビルトインモジュールがファイルの入出力やコンソールへ色付き文字を出力などの基本的な処理をサポートします
- ファイルの読み込みにエンコードを自動推測させることができるので、エンコードなどを気にせず開発が可能です
- パッケージ (モジュール) の外部公開や取得もサポートします
wes のインストール
wes へアクセスして wes.js をコピーするかコマンドプロンプトで下記コマンドを入力してダウンロードしてください。
bitsadmin /TRANSFER GetWES https://raw.githubusercontent.com/wachaon/wes/master/wes.js %CD%\\wes.js
使い方
wes index
wes に続けて起点となるファイルパスを入れてください。(.js
の拡張子は省略可能)
wes は実行したコマンドプロンプトのウィンドウに SendKeys()
で再度をコマンド送信します。
SendKeys()
の仕様上 wes の絶対パスに ascii 以外の文字があると、正しくコマンドを送信できません。
同様の理由で送信時に IME の入力モードが ascii 以外の場合も正しくコマンドが送信でません。
また、コマンドプロンプトで wes
のみで実行すると REP (Read-Eval-Print) が起動します。
スクリプトを入力後、Enter を3連続入力するとスクリプトを実行します。
REP を使用してサンプルを試してください。
Chakra
Chakra は JScript のランタイムを ECMA-262 3rd edition 相当から ECMAScript 2015+ が実行できるように変更します。
wes が面倒なエンジンの変更オプションも自動で入力してくれます。
モジュールシステム
wes では require(...)
や import ... from ...
でのモジュールの読み込みが可能です。
WSH 自体が非同期実行をサポートしていないので、dynamic import はサポート外になります。
また、require()
での ActiveX 読み込みもサポートします。
ファイルの読み書きやパスの合成など基本的な処理はビルトインモジュールがサポートします。
JScript にはない VBScript の機能を使用して ActiveX の型を調べるサンプル。
const { TypeName } = require('VBScript')
const FSO = require('Scripting.FileSystemObject')
console.log('%O', TypeName(FSO))
ビルトインモジュールを使用してファイルを読み込むサンプル。
readTextFileSync()
はファイルエンコードを推測して読み込みます。
const fs = require('filesystem')
const path = require('pathname')
const readme = path.resolve(__dirname, 'README.md')
const contents = fs.readTextFileSync(readme)
console.log(contents)
エンジンを Chakra にした場合には使用できなかった new ActiveXObject
を使用して JScript らしく記述したサンプル。
wes での new Enumerator
は Enumerator object ではなく Array を返します。
const { Enumerator, ActiveXObject } = require('JScript')
const FSO = new ActiveXObject('Scripting.FileSystemObject')
const dir = FSO.getFolder(__dirname).Files
const files = new Enumerator(dir)
files.forEach(file => console.log(file.Name))
WMI (Windows Management Instrumentation) を使用し、サービス一覧を取得するサンプル。
const { GetObject, Enumerator } = require('JScript')
const ServiceSet = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_Service")
new Enumerator(ServiceSet).forEach(service => console.log(
'Name: %O\nDescription: %O\n',
service.Name,
service.Description
))
パッケージ (モジュール) 公開と取得
モジュールを複数集めてひとまとまりにしたものを wes ではパッケージと呼ぶことにします。
GitHub リポジトリを利用してパッケージの公開と取得が可能です。
パッケージの公開にはいくつかの制約があります。
- 1 リポジトリに 1 パッケージのみ公開できます
- リポジトリ名がパッケージ名になります
- リポジトリ名とローカルリポジトリのディレクトリ名は同名にします
-
require()
やimport ... from ...
の記述はモジュールのトップレベルに記述します
パッケージの公開方法
公開するにはコマンドプロンプトで下記のコマンドを実行します。(index.js
がパッケージの起点ファイルの場合)
wes bundle index
コマンドを実行すると wes は必要なファイルを (動的に) 集めて 1 つの .json
ファイルにまとめます。
このファイルをプッシュしてください。
パッケージの取得方法
取得するにはコマンドプロンプトで下記のコマンドを実行します。
wes install @wachaon/calc
wes install
に続けて @author/package_name
形式で記述します。
製作者ごとにフォルダを分けたくないのであれば下記のコマンドを実行します。
wes install @wachaon/calc --unsafe --bare
グローバルでインストールしたい場合は下記のコマンドを実行します。
wes install @wachaon/calc --global
パッケージの紹介
@wachaon/edge
@wachaon/edge は Microsoft Edge based on Chromium (chromium版 edge) を自動操縦をサポートするパッケージです。
インストール
wes install @wachaon/edge
パッケージ以外に Microsoft Edge based on Chromium と web driver が必要になります。
web driver は @wachaon/edge をインストールしたあとに下記のコマンドを実行してください。
wes @wachaon/edge --download
インストールされている Microsoft Edge based on Chromium に適した web driver をダウンロードします。
zip を解凍してカレントディレクトリもしくは環境変数に登録されているディレクトリに msedgedriver.exe を配置してください。
(ダウンロードされたzipファイルは自動で解凍されます。)
使い方
手続き型形式のように処理を1つずつ記述もできますが、url をイベントに登録して、ブラウザがその url へ訪れた際に処理を実行するイベントドリブン形式でも記述できます。
イベントドリブン形式だと自動操縦での操作が難しい局面もあえてリスナーを登録しないことで、手動操作に切り替え可能です。
リスナーの url は文字列だけはなく、正規表現での登録も可能です。
プログラムを終了させるにはブラウザを閉じるか navi.emit('terminate', res)
を実行させてください。
window
のくわしい操作は @wachaon/webdriver を参照してください。
下記サンプルはブラウザを閉じるか https://www.yahoo
から始まる url に訪れるまでコマンドプロンプトに url を出力します。また、終了時には訪問した url の一覧をログファイルとして出力します。
const edge = require('@wachaon/edge')
edge((window, navi, res) => {
window.rect({
x: 1,
y: 1,
width: 1200,
height: 500
})
res.exports = []
navi.on(/https?:\/\/./, (url) => {
console.log('URL: %O', url)
res.exports.push(url)
})
navi.on(/^https?:\/\/www\.yahoo\b/, (url) => {
console.log('finished!')
navi.emit('terminate', res, window)
})
window.getStatus()
window.navigate('http://www.google.com')
})
online Visual Studio Code と wes を利用するば、レジストリを変更するようなインストールが規制されている環境でも、効率的に WSH の開発ができるようになります。