◆ V8 エンジンで JavaScript を実行できる
◆ .NET API を JavaScript 側から呼び出しもできる
◆ .NET を機能を使える JavaScript ランタイムとして使えそう

ClearScript

別のものを調べてたら偶然 ClearScript というものを見つけました
https://github.com/microsoft/ClearScript

ClearScript は .NET アプリから JScript や VBScript のスクリプトを実行できるというもので 理論的にはその他の Windows Script エンジンも動かせるようです

JScript や VBScript だとあまり嬉しさもないのですが ClearScript 5 から V8 にも対応したようです
.NET から V8 使えるなんて数千~数万くらいの Github のスターがありそうなのに 元が JScript などの需要低めだったからか今でも未だ 577 で少なめです
一応リポジトリは microsoft のもので公式なので個人でやってるものより品質はたしかだと思うのですけど

つかってみる

準備

.NET Core 対応なので新規プロジェクト作って ClearScript をインストールします

dotnet add package Microsoft.ClearScript --version 6.0.0

あと Visual C++ Redistributable libraries が必須です
ここに書かれています

https://github.com/microsoft/ClearScript/tree/master/NuGet/files

この 2 つをダウンロードしてインストールします

https://aka.ms/vs/16/release/vc_redist.x86.exe
https://aka.ms/vs/16/release/vc_redist.x64.exe

最初これに気づかずアセンブリのロードができないエラーが出て困りました
ドキュメントがそこまで充実してないのはちょっと不便です
こういうのはトップの README に書いておいてくれたらいいのですけど

実行する

コードはこういう感じです

using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

namespace cs
{
class Program
{
static void Main(string[] args)
{
using(var engine = new V8ScriptEngine()){
var result = engine.Evaluate(@"
1 + 2
");
System.Console.WriteLine(result);
}
}
}
}
3

エンジンのインスタンスを作って Evaluate や Execute メソッドに JavaScript コードを渡します
Evaluate なら式を評価してその結果が帰ってきます
JavaScript なら結果がほしいかどうかなので全部 Evaluate でも良さそうですが VB のような文か式で扱いが大きく違う場合はちゃんと使い分けが必要なので分かれてるようです

JavaScript から .NET API にアクセスする

JavaScript を実行するときに .NET 側のオブジェクトやクラスを JavaScript に渡すことができます
それを使うことで JavaScript から .NET の機能を使えます

.NET の出力メソッドを使って globalThis のプロパティ一覧を出力してみます

using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

namespace cs
{
class Program
{
static void Main(string[] args)
{
using(var engine = new V8ScriptEngine()){
engine.AddHostObject("dotnet", new HostTypeCollection("mscorlib", "System.Core"));

engine.Execute(@"
for(const name of Object.getOwnPropertyNames(globalThis)) {
dotnet.System.Console.WriteLine(name)
}
");
}
}
}
}
Object
Function
Array
Number
parseFloat
parseInt
Infinity
NaN
undefined
Boolean
String
Symbol
Date
Promise
RegExp
Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
globalThis
JSON
Math
console
ArrayBuffer
Uint8Array
Int8Array
Uint16Array
Int16Array
Uint32Array
Int32Array
Float32Array
Float64Array
Uint8ClampedArray
BigUint64Array
BigInt64Array
DataView
Map
BigInt
Set
WeakMap
WeakSet
Proxy
Reflect
decodeURI
decodeURIComponent
encodeURI
encodeURIComponent
escape
unescape
eval
isFinite
isNaN
SharedArrayBuffer
Atomics
WebAssembly
EngineInternal
dotnet

.NET を使える JavaScript 実行環境に

ここまででは直接 C# コード中に JavaScript のコードを含めていました
引数に JavaScript ファイルのパスを受け取って そのファイルの中身の文字列を Execute する exe ファイルを作っておけば JavaScript の実行環境にも使えます

runjs.exe file.js

これだけだと Node.js でいいのですが .NET の機能を使えるというのは Node.js にないメリットです
Windows を操作する用途だとこっちのほうが楽そうですし

V8 エンジンのフラグ

V8 エンジンのフラグを見るとリモートデバッグの有効化とか import 機能もあります
https://microsoft.github.io/ClearScript/Reference/html/T_Microsoft_ClearScript_V8_V8ScriptEngineFlags.htm

これだけできれば色々用途がありそうです