すぐに使えるJScript関数集

Windowsで動くJavaScriptこと**JScript**の関数集です。
コピペですぐに使えるように便利なものを集めています。


##ダイアログを表示する

ダイアログを表示します

```js:ダイアログを表示する
function alert(str){
    WScript.Echo(str);
}
```

##ファイルの内容を取得する

ファイルの内容を文字列として取得します。同期的

文字コードは"UTF-8"として取得します。
第二引数に文字コードを指定することもできます。例："Shift_JIS"

```js:ファイルの内容を取得する
function file_open(file, encode){
    var stream = WScript.CreateObject('ADODB.Stream');
    stream.charset = encode || "UTF-8";
    stream.Open();
    stream.loadFromFile(file);
    var contents = stream.ReadText();
    stream.close();

    return contents;
}
```

##ファイルに保存する

ファイルに文字列を保存します。同期的
ファイルが存在する場合は上書きし、存在しない場合はファイルを新規作成します。

文字コードは"UTF-8"として書き込まれます。
第三引数に文字コードを指定することもできます。例："Shift_JIS"

```js:ファイルに書き込む
function file_save(file, contents, encode){
    var stream = WScript.CreateObject('ADODB.Stream');
    stream.charset = encode || "UTF-8";
    stream.Open();
    stream.WriteText(contents);
    stream.SaveToFile(file, 2);
    stream.Close();
}
```

##ファイルの存在を確認する

ファイルが存在するかの真偽値を返します

```js:ファイルの存在を確認する
function file_exists(file){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");
    return fs.FileExists(file);
}
```


##ファイルをコピーする

ファイルをコピーします

```js:ファイルをコピーする
function file_copy(from, to){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");
    fs.CopyFile(from, to);
}
```


##ファイルを移動する

ファイルを移動します

```js:ファイルを移動する
function file_move(from, to){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");
    fs.MoveFile(from, to);
}
```

##ファイルを削除する

ファイルを削除します

```js:ファイルを削除する
function file_delete(file){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");
    fs.DeleteFile(file);
}
```


##ファイル一覧を取得する

フォルダに存在するファイル一覧を配列で返します

第二引数を'full'とするとファイル名がフルパスに、'base'とすると拡張子を除いたファイル名が返ります

```js:ファイル一覧を取得する
function file_list(dir, mode){
    var result = [];
    var fs     = WScript.CreateObject("Scripting.FileSystemObject");

    for (var e = new Enumerator(fs.GetFolder(dir).Files); !e.atEnd(); e.moveNext()){
        if(mode === 'base'){
            result.push(fs.GetBaseName(e.item()));
        }
        else if(mode === 'full'){
            result.push(e.item());
        }
        else{
            result.push(fs.GetFileName(e.item()));
        }
    }
    return result;
}
```

##フォルダを作成する

フォルダを作成します

```js:フォルダを作成する
function dir_create(dir){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");

    if(!fs.FolderExists(dir)){
        fs.CreateFolder(dir);
    }
}
```

##フォルダの存在を確認する

フォルダが存在するかの真偽値を返します

```js:フォルダの存在を確認する
function dir_exists(dir){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");
    return fs.FolderExists(dir);
}
```


##フォルダをコピーする

フォルダをコピーします

```js:フォルダをコピーする
function dir_copy(from, to){
    var fs = WScript.CreateObject("Scripting.FileSystemObject");
    fs.CopyFolder(from, to);
}
```

##URLエンコード/デコード

`encodeURIComponent()`と`decodeURIComponent()`が使用できます


##JSONエンコード
変数をJSON文字列に変換します

```js:JSONエンコード
function JSON_encode(obj){
    var htmlfile = WScript.CreateObject('htmlfile');
    htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=11">');
    return htmlfile.parentWindow.JSON.stringify(obj);
}
```

##JSONデコード
JSON文字列を変数に変換します

```js:JSONデコード
function JSON_decode(str){
    var htmlfile = WScript.CreateObject('htmlfile');
    htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=11">');
    return htmlfile.parentWindow.JSON.parse(str);
}
```

##HTTP_GET
URLにアクセスしてHTML文字列を返します。同期的

```js:HTTP_GET
function HTTP_GET(url){
    var http = WScript.CreateObject('Msxml2.ServerXMLHTTP');
    http.open('GET', url, false);
    http.send();
    return http.responseText;
}
```

##IEを操作する

IEを起動させて指定URLにアクセスします。
documentオブジェクトが返るので`querySelector()`などのメソッドが利用できます。

IEは非表示で起動しますが、第二引数に`true`を指定すると表示されます。

**※必ずスクリプト終了時に`IE.browser.Quit();`を実行してIEを終了させてください。**

```js:IE
function IE(url, visible){
    if(!IE.browser){
        IE.browser = WScript.CreateObject("InternetExplorer.Application");
        if(visible){
            IE.browser.Visible = true;
        }
    }
    IE.browser.navigate(url);
    while(IE.browser.Busy || IE.browser.readyState !== 4){
        WScript.Sleep(100);
    }
    return IE.browser.document;
}
```

IEの使用例。
Yahoo!Japan にアクセスして、titleタグの中身を取得し、表示します

```js:IEの使用例
var document = IE("https://www.yahoo.co.jp/");
var $title = document.querySelector('title');
WScript.Echo($title.textContent);
IE.browser.Quit(); //これを忘れずに！
```
##IEを使わず、windowを取得する

指定URLにアクセスし、windowオブジェクトを取得します。IEは起動しません。


```js:windowオブジェクトを取得する
function get_window(url){
    var http = WScript.CreateObject('Msxml2.ServerXMLHTTP');
    http.open('GET', url, false);
    http.send();

    var htmlfile = WScript.CreateObject('htmlfile');
    htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=11">' + http.responseText);
    return htmlfile.parentWindow;
}
```
get_windowの使用例。
Yahoo!Japan にアクセスして、titleタグの中身を取得し、表示します

```js:get_windowの使用例
var window = get_window("https://www.yahoo.co.jp/");
var $title = window.document.querySelector('title');
WScript.Echo($title.textContent);
```


##クリップボードに保存する

クリップボードに文字列を保存します

※DOS窓が一瞬表示されます

```js:クリップボードに保存する
function clip_set(str){
    var clip = WScript.CreateObject('WScript.Shell').Exec('clip');
    clip.StdIn.Write(str);
    clip.StdIn.Close();
    WScript.Sleep(50);
}
```

##クリップボードから取得する

クリップボードから文字列を取得します

```js:クリップボードから取得する
function clip_get(){
    var clip = WScript.CreateObject("htmlfile").parentWindow.clipboardData;
    return clip.getData("text");
}
```

##現在の日付を取得する

現在の日付を`"yyyy/mm/dd hh:mm:ss"`形式で返します

```js:現在の日付を取得する
function date(){
    var d      = new Date();
    var year   = d.getFullYear();
    var month  = ('0' + (d.getMonth()+1)).slice(-2);
    var day    = ('0' + d.getDate()).slice(-2);
    var hour   = ('0' + d.getHours()).slice(-2);
    var minute = ('0' + d.getMinutes()).slice(-2);
    var second = ('0' + d.getSeconds()).slice(-2);

    return year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second;
}
```

##コマンドを実行する

任意のコマンドを実行します。同期的

```js:コマンドを実行する
function run(command){
    var shell = WScript.CreateObject('WScript.Shell')
    shell.Run(command, 1, true)
}
```

##引数を配列で取得する
コマンドライン引数を配列で取得します。引数が存在しない場合は空配列です。

```js
function get_args(){
    var args = []
    for(var i = 0; i < WScript.Arguments.Count(); i++){
        args.push(WScript.Arguments(i))
    }
    return args
}
```

##終了する
スクリプトを直ちに終了します

```js:終了する
function exit(){
    WScript.Quit()
}
```

##多重起動防止

スクリプトの多重起動を防止します。
同じスクリプトが起動していたら、警告ダイアログを表示して終了します

```js:多重起動防止
function SingleInstance(){
    var process = GetObject("WinMgmts:").ExecQuery("Select * From Win32_Process")
    var count   = 0

    for(var e = new Enumerator(process); !e.atEnd(); e.moveNext()){
        if(e.item().ExecutablePath === WScript.FullName && String(e.item().CommandLine).indexOf(WScript.ScriptFullName) > -1){
            count++
        }
    }

    if(count > 1){
        WScript.Echo(WScript.ScriptName + " is already running")
        WScript.Quit()
    }
}
```

##入力ダイアログ

JScriptには入力ダイアログが存在しませんが、VBScriptから輸入すると使えるようになります。

![wsf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70356/51c502b7-6ca8-c7f8-1415-85e8db293595.png)


JScriptとVBScriptを混成するには、次のような`wsf`ファイルを作成します。
すると、JScriptで`prompt`関数が使えるようになります。


```xml:sample.wsf
<job>
<script language="VBScript">
function prompt(message, title, value)
    prompt = InputBox(message, title, value)
end function
</script>

<script language="JScript">
var input = prompt('説明文', 'タイトル', '初期値');
WScript.Echo(input); //入力された内容が表示される
</script>
</job>
```

##高度なGUI

高度なGUIアプリを作りたい場合は、次のような``hta``ファイルを作成します。

```html:exmple.hta
<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>HTAアプリ</title>

<ul>
  <li><a id="notepad" href="#">メモ帳を起動する</a></li>
</ul>

<script>
const shell = new ActiveXObject('wscript.shell');
document.querySelector("#notepad").addEventListener("click", function (){
    shell.run("notepad");
});
</script>
```

HTMLとCSSを使ってGUIを記述できます。
JavaScriptで``const``が使えるので、IE11相当で動いていると思います。

注意する点として**WScriptオブジェクト**が使えないので、代わりに**new ActiveXObject()**を利用します。

##ポリフィル

JScriptはES3相当なので、足りないメソッド(特に`Array.indexOf`)はポリフィルで補完しましょう。


```js:Array.prototype.indexOf
Array.prototype.indexOf = function(obj, start){
    for(var i = (start || 0), j = this.length; i < j; i++){
        if(this[i] === obj){
            return i
        }
    }
    return -1
};
```