バッチファイルにJavaScript/JScript.NETコードを書く

# 注意
* 実用性は不明です。

# 方法
バッチファイル内にPowerShellスクリプトを書くことができます。
　(参考 : [バッチファイルから PowerShell を呼び出す方法](http://qiita.com/cd01/items/82829ba0ec0f59e1b04d) )

PowerShellスクリプト内にJavaScriptプログラムを書くことができます。
　(参考 : [powershellでJavascriptコードを実行する](http://blog.livedoor.jp/morituri/archives/53997724.html) )

PowerShellスクリプト内にJScript.NET（≒JavaScript）プログラムを書くことができます。
　(参考 : [PowerShellでJScript.NETのコードを実行する](http://winscript.jp/powershell/221) )

組み合わせると、
バッチファイル内にJavaScriptまたはJScript.NET（≒JavaScript）コードを書くことができます。

# サンプル(ver.1)

(2017/7/17追記)こちらはx86(32bit)プロセスからの実行専用です。x64(64bit)プロセスから実行するとエラーになります。
→ ver.3をご利用ください。

以下をバッチファイル "hello.bat" に保存して、"hello.bat 1" を実行すると、"hello 1 world"が2行表示されます。

```ps1
@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof

# http://qiita.com/cd01/items/82829ba0ec0f59e1b04d
# http://blog.livedoor.jp/morituri/archives/53997724.html

Param($argBat)

$objjs = New-Object -comobject ScriptControl
$objjs.Language = "Javascript"
$src = @'
function helloFunc(arg) {
  msg = "hello " + arg + " world";
  print(msg);
  return msg;
}
var log = "";
function print(v) {
  log += v;
}
function readLog() {
  return log;
}
'@
$objjs.Eval($src)

$helloResult = $objjs.CodeObject.helloFunc($argBat)
Write-Output -InputObject $helloResult
Write-Output -InputObject $objjs.CodeObject.readLog()

exit 0
```

# サンプル(ver.2)

(2017/7/17追記)ver.1と違い、x64(64bit)プロセスからも実行できるバージョンです。
(2017/7/17追記)バッチファイル内でx64(64bit)専用exeを呼び出すとエラーになると予想されます。x86用exeを呼ぶなら問題ありません。
→ ver.3をご利用ください。

以下をバッチファイル "hello.bat" に保存して、"hello.bat 1" を実行すると、"hello 1 world"が2行表示されます。

```ps1
@%windir%\SysWOW64\cmd.exe /C powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof

# http://qiita.com/cd01/items/82829ba0ec0f59e1b04d
# http://blog.livedoor.jp/morituri/archives/53997724.html

Param($argBat)

$objjs = New-Object -comobject ScriptControl
$objjs.Language = "Javascript"
$src = @'
function helloFunc(arg) {
  msg = "hello " + arg + " world";
  print(msg);
  return msg;
}
var log = "";
function print(v) {
  log += v;
}
function readLog() {
  return log;
}
'@
$objjs.Eval($src)

$helloResult = $objjs.CodeObject.helloFunc($argBat)
Write-Output -InputObject $helloResult
Write-Output -InputObject $objjs.CodeObject.readLog()

exit 0
```

# サンプル(ver.3)

(2017/7/21追記)x64/x86の制約なしに実行できるバージョンです。つまりx64環境で実行でき、おそらくbatからx64専用プロセスを呼び出すことも可能です。
(2017/7/21追記)ver.1～ver.2と違い、JScript.NET（≒JavaScript）を使ったものです。Console.WriteLine()も使えます。

以下をバッチファイル "hello.bat" に保存して、"hello.bat 1" を実行すると、"hello 1 world"が2行表示されます。

```ps1
@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof

# http://qiita.com/cd01/items/82829ba0ec0f59e1b04d
# http://winscript.jp/powershell/221

Param($argBat)

$src = @'
static function helloFunc(arg) {
  var msg = "hello " + arg + " world";
  Console.WriteLine(msg);
  return msg;
}
'@
$JScNet = (Add-Type -Language JScript -MemberDefinition $src -Name "JScNet" -PassThru)[1]
$helloResult = $JScNet::helloFunc($argBat)

Write-Output -InputObject $helloResult

exit 0
```


# 関連情報
* [バッチファイルから PowerShell を呼び出す方法](http://qiita.com/cd01/items/82829ba0ec0f59e1b04d)
* [powershellでJavascriptコードを実行する](http://blog.livedoor.jp/morituri/archives/53997724.html)
* [gist batファイル内のPowerShell内のJavaScriptプログラムを動かす](https://gist.github.com/cat2151/95e39bd148c19ea1a45d02b5bf75914c)
* [gist batファイル内のPowerShell内のJScript.NET（≒JavaScript）プログラムを動かす](https://gist.github.com/cat2151/48c1bb91558369815f6ddc06177380df)
* [バッチファイルにC#コードを書く](http://qiita.com/cat2151/items/0f60bb6ab0ca811346d1)