WSHを利用したローカルアプリケーション

マンガで分かる JavaScriptプログラミング講座

マンガで分かる JavaScriptプログラミング講座 第2版



第3部 Webページのプログラミング
第25話:WSHを利用したローカルアプリケーション

目次



マンガ
















マンガ台詞

【1Page】
先生:今回はWebページから離れて
    ローカルアプリケーション をJavaScriptで作るぞ
遊:ローカルアプリケーション?
先生:EXEファイルみたいに ダブルクリックで実行したり
    ドラッグ&ドロップで 起動したりするソフトだ
守:へー JavaScriptで 作れるんですか?
先生:ああ 『WSH』を使えば作れる
        WSH = Windows Script Host
    というわけで 俺が作った テンプレート を示すぞ
【2Page】
        【sample.wsf】
        <job id="main">
            <script language="JavaScript" src="cmnFunc.js"></script>
            <script language="JavaScript">
                // グローバル変数
                var args;    // 引数
                var dropFilePath = "";    // ドロップ ファイルのパス
                var dropFileStr  = "";    // ドロップ ファイルの中身の文字列

                // メイン ルーチン
                init();    // 初期化処理
                main();    // メイン処理

                // 初期化処理
                function init() {
                    args = WScript.Arguments;    // 引数のオブジェクト
                    if (args.length >= 1) {
                        dropFilePath = args(0);
                        dropFileStr  = cmnFunc.readFile(dropFilePath);
                    }
                }

                // メイン処理
                function main() {
                    if (dropFilePath == "") {
                        WScript.Echo("ドロップ ファイルなし");
                    } else {
                        WScript.Echo(dropFilePath + "\n" + dropFileStr);
                    }
                }
            </script>
        </job>
【3Page】
先生:ダブルクリックで アラートが出る
        sample.wsf
        ドロップ ファイルなし
    ファイルをドロップすれば 中身を表示する
        sample.wsf
        紹介.txt
        安見遊は体を動かしたくない面倒くさがり屋の女の子
    このソースを見て 気付いた点はあるか?
守:『<job>』や『<script>』 というタグがありますね
    なんだかHTMLファイルみたいです
        <job id="main">〜</job>
        <script language="JavaScript">〜</script>
麗:あと『cmnFunc.js』という 外部ファイルも 読み込んでいますね
    これもHTMLファイルに 似ています
        <script language="JavaScript" src="cmnFunc.js"></script>
【4Page】
遊:でも これって HTMLファイルじゃ 見ないわよ
    それに『WScript』という 変なものもあるし
        WScript.Echo("ドロップ ファイルなし");
先生:みんな いいところに 気が付いた
    Webページのプログラムでは 『window』オブジェクトを利用した
    WSHのプログラムでは 『WScript』オブジェクトを利用する
        // 例)ダイアログの出し方の違い
        window.alert("文字列");    // Webページ
        WScript.Echo("文字列");    // WSH
守:なるほど ところで 『cmnFunc.js』には 何が入っているん ですか?
先生:これもソースを 示しておこう
【5Page】
        【cmnFunc.js】
        var cmnFunc = new function() {
            // オブジェクトの作成
            this.createObject = function(name) {
                return WScript.CreateObject(name);
            };

            // WScriptのシェル
            // ファイル システム オブジェクト
            // 実行ファイルのパス
            // ルート ディレクトリ
            this.wshell = this.createObject("WScript.Shell");
            this.fs = this.createObject("Scripting.FileSystemObject");
            this.rootPath = WScript.ScriptFullName;
            this.rootDir = this.fs.GetFile(this.rootPath).ParentFolder;

            // ファイルに文字列を書き込み
            this.writeFile = function(path, data) {
                var stream = this.fs.CreateTextFile(path, true);
                stream.Write(data);
                stream.Close();
            };

            // ファイルから文字列を読み込み
            this.readFile = function(path) {
                if (this.fs.FileExists(path) == 0) return "";
                var stream = this.fs.OpenTextFile(path, 1);
                var rdStr = "";
                try {rdStr = stream.ReadAll();} catch(e){}
                stream.Close();
                return rdStr;
            };
        }
【6Page】
先生:ファイル入出力 の関数を 用意しておいた
    このテンプレート を利用すれば 簡単にソフトが できるぞ
麗:あの 先生
    テンプレートを見ても どんなソフトを 作れるか分かりません
先生:あー そうか
    これまでの プログラムとは 大きく違うからな
    よし どんなものが 作れるか 例を挙げよう
        テキストファイルを HTMLファイルに変換するツール
        ファイル内の 漢字 平仮名 片仮名の数を 調査するツール
    『sample.wsf』の 『メイン処理』を 書き換えれば
    いろいろなソフト を作れるぞ
        function main() {〜}
遊:はいはいはーい
    作ったわ!
先生:早いな 何を 作ったんだ?
遊:ファイルを 暗号化する ツールよ
【7Page】
先生:おっ 凄いじゃないか
    どれどれ
        (10KBのテキストをドロップ。1KBになる)
        yuuApli.wsf
        紹介.txt    10KB
        yuuApli.wsf
        紹介.txt    1KB
    うん?
        (ダブルクリック)
        紹介.txt    1KB
        紹介.txt
        ファイル(F)  編集(E)  書式(O)
        暗号化
    おい ファイルの中に 『暗号化』と書いた だけじゃないか
遊:どう?
    中身が絶対にばれないわよ!
    (自信ありげ)
先生:はー
    プログラムの 技術がついても
    頭はよくならないな



説明

この章では、『WSHを利用したローカルアプリケーション』について学びます。

Windowsパソコンには、JavaScriptを使ってローカルアプリケーションを作成する仕組みが用意されています。それが『WSH』です。この『WSH』を利用したアプリケーションの作成には、これまで学んだJavaScriptの知識を利用することができます。

それでは以下、『WSH』を利用したアプリケーションの作成方法を紹介していきます。



『WSH』とは?

『WSH』(Windows Script Host)は、テキストファイルに書いたプログラムを実行する、Windows上の環境です。

『WSH』では、『VBScript』と『JavaScript』(正確にはJScript)が標準で利用できます。

本講座では、JavaScriptでプログラムを行っていきます。


参考:Windows Script World



『WSF』とは?

Windowsでは、拡張子『.js』のファイルをダブルクリックすることで、JavaScriptで書かれた『WSH』のプログラムを実行できます。

しかし、この拡張子『.js』のファイルは、正しく実行できないことがあります。これは、インストールしているソフトによって、関連付けが変更されているのが原因です。

関連付けというのは、どの拡張子のファイルを、どのソフトで開くかという設定です。Windowsでは、拡張子とソフトを対応させています。そして、ファイルをダブルクリックすると、特定のソフトで開くようにしています。

そのため、関連付けが変更されると、ファイルを実行しても、意図した動作にならないことがあります。拡張子『.js』のファイルは、Webサイト構築ソフトなどによって、関連付けが変更されていることがよくあります。

本講座では、この拡張子『.js』のファイルではなく、XML形式(HTMLのようにタグが付いたテキストファイル)でスクリプトを記述する『WSF』(Windows Script File)を利用します。

『WSF』では、ファイルの拡張子を『.wsf』とします。このファイルをダブルクリックしたり、このファイルに他のファイルをドロップすることで、『WSH』のプログラムを実行できます。

『WSF』の書き方

『WSF』のファイルは、『<job id="〜">〜</job>』とうタグで全体を囲います。以下、基本的な構造です。

<job id="main">
    <script language="JavaScript">
        // プログラム
    </script>
</job>

また、文字化けなどで正しく動作しない場合は、文字コードを明示的に指定することもできます。

<?xml version="1.0" encoding="shift-jis" ?>
<job id="main">
    <script language="JavaScript">
        // プログラム
    </script>
</job>

参考:msdn - Windows スクリプト ファイル (.wsf) を使用する
参考:msdn - Windows Script Host



『WSH』のテンプレート

マンガで出てきた『WSH』のテンプレートについて解説を行います。以下、『sample.wsf』のソースコードです。

<job id="main">
    <script language="JavaScript" src="cmnFunc.js"></script>
    <script language="JavaScript">
        // グローバル変数
        var args;    // 引数
        var dropFilePath = "";    // ドロップ ファイルのパス
        var dropFileStr  = "";    // ドロップ ファイルの中身の文字列

        // メイン ルーチン
        init();    // 初期化処理
        main();    // メイン処理

        // 初期化処理
        function init() {
            args = WScript.Arguments;    // 引数のオブジェクト
            if (args.length >= 1) {
                dropFilePath = args(0);
                dropFileStr  = cmnFunc.readFile(dropFilePath);
            }
        }

        // メイン処理
        function main() {
            if (dropFilePath == "") {
                WScript.Echo("ドロップ ファイルなし");
            } else {
                WScript.Echo(dropFilePath + "\n" + dropFileStr);
            }
        }
    </script>
</job>

先ほど説明したとおり、全体を『<job id="main">〜</job>』と囲い、その中に『<script>』タグを使ってプログラムを書いています。

『src="cmnFunc.js"』として読み込んでいる『cmnFunc.js』は、本講座用に用意した共通関数を収録した、外部JavaScriptファイルです。このファイルには、ファイルの入出力を行うための関数を収録しています。

それでは以下、起動してから行われる処理を順番に見て行きます。

ダブルクリック、もしくはファイルのドロップで起動した『sample.wsf』は、『メイン ルーチン』の2つの関数を実行します。まずは『init』という初期化処理を行う関数を実行します。そして次に、『main』というメイン処理を行う関数を実行します。

初期化処理

『init』内で行う初期化処理では、『WScript.Arguments』という、引数を表すオブジェクトを、変数『arg』に入れています。

これまで出てきた『関数の引数』は、関数のあとの括弧内に書かれる変数でした。『ファイル実行時の引数』は、実行ファイルにドロップした『ファイルのパス』になります。『sample.wsf』に『紹介.txt』というファイルをドロップした場合は、『紹介.txt』のフルパス(完全なパス)が、引数になります。

この引数の数が1以上の場合は、『ファイル実行時の引数』が存在します。そこで、『if (args.length >= 1)』と引数の数を確認して、『1』以上ならば『dropFilePath = args(0)』として、引数を取り出しています。そして、このファイルのパスを元にして、『cmnFunc.readFile』メソッドを利用して、ファイルの中身を変数『dropFileStr』に読み込んでいます。

メイン処理

メイン処理では、ドロップファイルのパスがあるかどうかで、処理を分岐させています。

ドロップファイルのパスが空の場合は、ダイアログを開いて、『ドロップ ファイルなし』と表示させています。また、ドロップファイルのパスが存在する場合は、ダイアログを開いて、ドロップファイルのパスと、その中身の文字列を表示させています。

ここで注意するのは『WScript.Echo』メソッドです。『WSH』のプログラムでは、Webページのプログラムと違って『window』オブジェクトが存在しません。そのために『window.alert』メソッドもありません。また、『window.document』といったオブジェクトも利用できません。

『WSH』のプログラムでは、『window』オブジェクトの代わりに『WScript』オブジェクトを利用します。このオブジェクトには『Echo』という、『alert』のようにダイアログを表示するメソッドが用意されています。そこでこの『Echo』メソッドを利用して、ダイアログを表示します。

『cmnFunc.js』

『cmnFunc.js』についても、ソースを示します。こちらは少し高度ですので、理解できない場合は読み飛ばしても構いません。この『cmnFunc.js』のように、外部JavaScriptファイルとして利用するプログラムは、中身を理解していなくても利用できます。

var cmnFunc = new function() {
    // オブジェクトの作成
    this.createObject = function(name) {
        return WScript.CreateObject(name);
    };

    // WScriptのシェル
    // ファイル システム オブジェクト
    // 実行ファイルのパス
    // ルート ディレクトリ
    this.wshell = this.createObject("WScript.Shell");
    this.fs = this.createObject("Scripting.FileSystemObject");
    this.rootPath = WScript.ScriptFullName;
    this.rootDir = this.fs.GetFile(this.rootPath).ParentFolder;

    // ファイルに文字列を書き込み
    this.writeFile = function(path, data) {
        var stream = this.fs.CreateTextFile(path, true);
        stream.Write(data);
        stream.Close();
    };

    // ファイルから文字列を読み込み
    this.readFile = function(path) {
        if (this.fs.FileExists(path) == 0) return "";
        var stream = this.fs.OpenTextFile(path, 1);
        var rdStr = "";
        try {rdStr = stream.ReadAll();} catch(e){}
        stream.Close();
        return rdStr;
    };
}

以下、プログラム自体の解説は高度になるので、使い方だけを示します。

『<script language="JavaScript" src="cmnFunc.js"></script>』としてファイルを読み込んだあと、以下のメソッドを利用することができます。

書き方引数戻り値説明
cmnFunc.readFile(path)『path』は、読み込むファイルのパス読み込んだ
ファイルの文字列
ファイルを文字列
として読み込む
cmnFunc.writeFile(path, data)『path』は、書き込むファイルのパス
『data』は、書き込む内容
なしファイルに文字列を
上書きする

また、『cmnFunc』では、以下のプロパティを利用できます。

書き方説明
cmnFunc.rootPath『cmnFunc.js』のフルパス
cmnFunc.rootDir『cmnFunc.js』の保存されているディレクトリ
cmnFunc.wshellOSのシェルを操作するオブジェクト
cmnFunc.fsファイル システム オブジェクト



『WScript』と『ActiveXObject』

『WSH』のプログラミングでは、OSの機能を利用したり、ファイルの入出力を行ったりできます。また、『ActiveX』と呼ばれる一連のオブジェクトを利用して、様々な処理を行えます。

『WSH』では、『WScript』が、Webページのプログラミングでの『window』のような、基本のオブジェクトになっています。

例えばダイアログ表示は、Webページでは『window.alert』でしたが、『WSH』では『WSH.Echo』になります。

// Webページ
window.alert("message");

// 『WSH』
WSH.Echo("message");

『WScript』から呼び出せる様々なオブジェクト

こういった違いの他に、『WSH』のプログラミングでは、様々なオブジェクトを『WScript』から呼び出せます。

var wshell = WScript.CreateObject("WScript.Shell");
var fs = WScript.CreateObject("Scripting.FileSystemObject");

1行目のプログラムでは、『WScript』を利用して『WScript.Shell』という、シェル(OS)を操作するオブジェクトを呼び出しています。

2行目のプログラムでは、同様に『Scripting.FileSystemObject』という、ファイルを操作するオブジェクトを呼び出しています。

『ActiveX』オブジェクト

オブジェクトの呼び出しは、『WScript』以外から行われることもあります。『ActiveX』と呼ばれる一連のオブジェクトを利用する場合は『new ActiveXObject()』として呼び出します。

var ado = new ActiveXObject("ADODB.Stream");

『WSH』で利用できるオブジェクトは無数にあります。行いたい処理に合わせて、どんなオブジェクトを利用できるか、ネットや本で調べてください。


参考:WSH@Workshop - WSHのサンプル集&リファレンス



『WSH』を利用したアプリケーションの実例

以下、『WSH』を利用して、Yahoo!ニュースのRSSをダウンロードするプログラムの実例を示します。参考にして、各自便利なプログラムを作成してください。

以下、『sample2.wsf』のソースコードです。『sample2.wsf』をダブルクリックすれば、Yahoo!ニュースのRSS『http://dailynews.yahoo.co.jp/fc/rss.xml』を取得して、ローカルに保存します。また、保存したフォルダをExplorerで開きます。

少し高度になりますが、このプログラムの意味が全て分かれば、JavaScriptの腕前はかなりのレベルに到達していると言えるでしょう。

<job id="main">
    <script language="JavaScript" src="cmnFunc.js"></script>
    <script language="JavaScript" src="cmnFunc.exec.js"></script>
    <script language="JavaScript" src="cmnFunc.download.js"></script>
    <script language="JavaScript">
        // メイン ルーチン
        main();    // メイン処理

        // メイン処理
        function main() {
            var resText = cmnFunc.download(
                "http://dailynews.yahoo.co.jp/fc/rss.xml",
                "dailynews_yahoo_rss.xml"
            );
            WScript.Echo("取得した文字列の長さ : " + resText.length);
            cmnFunc.run("explorer.exe", cmnFunc.rootDir);
        }
    </script>
</job>

以下、『cmnFunc.js』です。

var cmnFunc = new function() {
    // オブジェクトの作成
    this.createObject = function(name) {
        return WScript.CreateObject(name);
    };

    // WScriptのシェル
    // ファイル システム オブジェクト
    // 実行ファイルのパス
    // ルート ディレクトリ
    this.wshell = this.createObject("WScript.Shell");
    this.fs = this.createObject("Scripting.FileSystemObject");
    this.rootPath = WScript.ScriptFullName;
    this.rootDir = this.fs.GetFile(this.rootPath).ParentFolder;

    // ファイルに文字列を書き込み
    this.writeFile = function(path, data) {
        var stream = this.fs.CreateTextFile(path, true);
        stream.Write(data);
        stream.Close();
    };

    // ファイルから文字列を読み込み
    this.readFile = function(path) {
        if (this.fs.FileExists(path) == 0) return "";
        var stream = this.fs.OpenTextFile(path, 1);
        var rdStr = "";
        try {rdStr = stream.ReadAll();} catch(e){}
        stream.Close();
        return rdStr;
    };
}

以下、『cmnFunc.run.js』です。

// 先に『cmnFunc.js』を読み込んでおく
if (typeof(cmnFunc) != "undefined") {
    // EXEを実行
    // 引数1:『path』実行ファイルのパス。もしくは、開きたいファイル
    // 引数2:『option』引数1で実行ファイルを指定した場合の起動オプション
    // 引数3:『wait』0なら待機なし、1なら待機あり、デフォルト0
    cmnFunc.run = function(path, option, wait) {
        if (wait != 0 && wait != 1) wait = 0;
        try {
            var runPath = '"' + path + '"';
            if (option != "") runPath += ' "' + option + '"';
            this.wshell.Run(runPath, 10, wait);
        } catch(e) {
            var runPath = path;
            if (option != "") runPath += ' ' + option;
            this.wshell.Run(runPath, 10, wait);
        }
    }
}

以下、『cmnFunc.download.js』です。

// 先に『cmnFunc.js』を読み込んでおく
if (typeof(cmnFunc) != "undefined") {
    // EXEを実行
    // 引数1:『url』ダウンロードするファイルのURL
    // 引数2:『path』保存ファイル名、もしくはパス、空時は保存なし
    // 戻り値:テキストの場合は文字列、失敗時は『err』
    cmnFunc.download = function(url, path) {
        var progIDs = [
            "Msxml2.ServerXMLHTTP.6.0",
            "Msxml2.ServerXMLHTTP.5.0",
            "Msxml2.ServerXMLHTTP.4.0",
            "Msxml2.ServerXMLHTTP.3.0",
            "Msxml2.ServerXMLHTTP",
            "Microsoft.ServerXMLHTTP",
            "Msxml2.XMLHTTP.6.0",
            "Msxml2.XMLHTTP.5.0",
            "Msxml2.XMLHTTP.4.0",
            "Msxml2.XMLHTTP.3.0",
            "Msxml2.XMLHTTP",
            "Microsoft.XMLHTTP"
        ]; 

        var xmlHttp;
        var resText;
        var resBody;
        for (var i = 0; i < progIDs.length; i ++) {
            try {
                xmlHttp = new ActiveXObject(progIDs[i]);
                if (typeof(xmlHttp) == "undefined") break;
            } catch(e){}
        }
        if (typeof(xmlHttp) == "undefined") return "err";

        try {
            xmlHttp.open("GET", url, 0);    // 0 : 同期処理
            xmlHttp.send("");
            resText = xmlHttp.responseText;
            resBody = xmlHttp.responseBody;
        } catch(e){}
        xmlHttp = null;
        if (path == "") return resText;

        var ado;
        try {
            ado = new ActiveXObject("ADODB.Stream");
            ado.Type = 1;    // 1 : バイナリ
            ado.open()
            ado.write(resBody)
            ado.saveToFile(path, 2);    // 2 : 上書き保存
            ado.close();
            ado = null;
        } catch(e){
            if (ado != null) {
                try {ado.close();} catch(e){}
                ado = null;
            }
            return "err";
        }
        return resText;
    }
}



サンプルの入手

以下は、今回出てきたサンプルです。

ZIPでまとめてダウンロード (右クリックから保存してください)

sample.wsf』(テンプレート)(右クリックから保存してください)

cmnFunc.js』(共通関数)(右クリックから保存してください)

sample2.wsf』(ニュースのRSSをダウンロード)(右クリックから保存してください)

cmnFunc.run.js』(ファイルを実行関数)(右クリックから保存してください)

cmnFunc.download.js』(ダウンロード関数)(右クリックから保存してください)

プログラムの中身を見たい場合は、それぞれのHTMLファイルをブラウザで開いたあと、右クリックをして『ソースの表示』を選択してください。

メモ帳で、ファイルの中身を見ることができます。

≫ 「マンガで分かる JavaScriptプログラミング講座」トップに戻る


『柳井政和』 の初心者向け講座

『柳井政和』 のサイト

マンガで分かる Java入門講座
Javaのオブジェクト指向を解説するサイトです。
Webページ100ページ以上、マンガ800ページ以上で
解説を行っています。


PuzzleAndGame.com
JavaScriptで作ったゲームが中心のサイト。
タワーディフェンス、リバーシ、パズルゲームなどを公開。
Webブラウザ、PCアプリ、Androidアプリとして動作。


クロクロ・ツールズ
全てJavaScriptで作られた、ブラウザから利用できる各種アプリケーションです。
HTML5に対応しているモダンブラウザから使えます。
ブックマークに入れるなどして、ご利用ください。


『柳井政和』 執筆の本

「裏切りのプログラム ハッカー探偵 鹿敷堂桂馬」
文藝春秋より発売(2016年8月27日発売、予約注文可能です)。
2016年の松本清張賞で、最終候補に残った小説です。
プログラマー鹿敷堂桂馬が、女性社長の安藤裕美とともに、
IT業界で起きた事件の解決に挑みます。
プログラマーが探偵役のエンタメ・ミステリーです。


「JavaScript 仕事の現場でサッと使える! デザイン教科書」
プログラミング初心者向けに、様々な利用例を元に、プログラムとJavaScriptを解説する本。
プログラム自体が初めての方にも、なるべく分かりやすいように書いています。
技術評論社より発売。


「プログラマのためのコードパズル〜JavaScriptで挑むコードゴルフとアルゴリズム」
コードゴルフやアルゴリズム問題、その解説、関連知識の紹介を行った本です。
プログラマーなら、楽しめる内容になっています。
技術評論社より発売。


「マンガでわかるJavaScript」
本講座が書籍になりました。 本用に、より分かりやすく、読みやすく、再構成して書き直しました。
よければ、手にとっていただけると嬉しいです。
秀和システムより発売。


「マンガでわかるJavaプログラミング」
プロ部の面々が、今度はjavaのプログラミングに挑戦。
javaを1から学ぶ人向けの書籍です。
秀和システムより発売。 詳細情報


古い本
HTML5&JavaScript本格ゲームプログラミング 〜ライブラリ自作からはじめるブラウザゲーム開発
マンガでわかるAndroidプログラミング 第2版
Google Androidアプリ開発ガイド 第3版
プロならば知っておくべきWebコーディング&デザインの定石100

『柳井政和』 開発のWebアプリやソフトなど

PuzzleAndGame.com
全自動4コマ
全自動百科事典(オートペディア)
全自動似顔絵
新刊・新作カレンダー
EX リバーシ
全自動迷路
めもりーくりーなー
ラジオ・ブラウザ
PCソフト
マンガで分かる JavaScriptプログラミング講座
スクリーンセーバー「なう」
開発元:クロノス・クラウン




Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2017 Cronus Crown (c)1997-2017 Masakazu Yanai
このWebPageに関するご意見・お問い合わせは
サイト情報 - 弊社への連絡 -
までお願いします。