Как реализовать Jint (интерпретатор JavaScript) в приложении WinForms на C #

Вы когда-нибудь работали с Node.js? Node.js — это инструмент командной строки с открытым исходным кодом, созданный для серверного кода JavaScript. Одним словом, это просто вещь, которую можно обрабатывать динамическим языком (JavaScript), чтобы делать разные вещи на виртуальной машине, которая невероятно быстра (V8). Node.js следует принципу использования нативных привязок в C ++, теперь представьте себе программирование (с той же привязкой) на JavaScript с мощью C #! Используя Jint, вы сможете сделать то же самое, что и с Node.js, но с C # вместо C ++.

Jint — это интерпретатор Javascript для .NET, который обеспечивает полное соответствие ECMA 5.1 и может работать на любой платформе .NET, поскольку он не генерирует никакого байт-кода .NET и не использует DLR, он быстрее запускает относительно небольшие сценарии. Основными особенностями Jint являются:

Кроме того, Jint является поддерживаемым проектом, это означает, что грядущее обновление для ECMAScript 6 будет возможно когда-нибудь.

В этой статье вы узнаете, как установить и использовать замечательный Jint JS Interpreter в вашем приложении WinForms.

Установка Jint с NuGet

Первое, что нам нужно сделать, это установить пакет Jint с помощью диспетчера NuGet. Установка пакета из Visual Studio действительно проста, просто найдите область обозревателя решений в правой верхней части VS, затем щелкните правой кнопкой мыши свой проект и в раскрывающемся меню выберите Управление пакетами NuGet:

Теперь должен запуститься менеджер пакетов NuGet, и вы сможете установить пакеты в свой проект. Перейдите на вкладку «Обзор» всплывающего окна и выполните поиск jint, в списке это должен быть первый элемент в списке (убедитесь, что автором является Себастьян Рос), выберите его и нажмите «Установить»:

Установите Jint Javascript Interpreter в проект WinForms

После завершения установки Jint вы сможете работать с этим потрясающим пакетом в своем проекте. Для получения дополнительной информации о проекте Jint, пожалуйста, посетите официальный репозиторий Github здесь.

Использование Jint

Перед работой с кодом не забудьте включить Jint в ваш класс C # (где бы вы ни хотели использовать интерпретатор JS):

using Jint;

Чтобы понять, как работает Jint, нет лучшего способа показать его на примерах. В некоторых примерах нам понадобится форма с 2 элементами, кнопка, обозначенная как button1 и многострочное текстовое поле, обозначенное как textBox1, который будет содержать скрипт, который вы хотите запустить:

Предоставить собственные функции JavaScript

Чтобы понять, как легко манипулировать нативным кодом с помощью JavaScript, мы сосредоточимся на наиболее классическом и простом для понимания примере. Как вы знаете, в браузере alert Функция генерирует диалог, который показывает сообщение пользователю. Эта функция ожидает в качестве уникального аргумента строку, которая представляет сообщение, которое необходимо показать пользователю (alert("Message")).

Поскольку Jint не браузер, а интерпретатор JavaScript, такой функции оповещения или DOM не существует в движке JavaScript. Поэтому давайте создадим очень простую функцию оповещения в C #, которая отображает окно сообщения с некоторым текстом внутри:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// Import Jint
using Jint;
namespace Sandbox
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
///
/// Native alert function that shows a dialog with the specified message.
///
///
private void Alert(string Message)
{
MessageBox.Show(Message, "Window Alert", MessageBoxButtons.OK);
}
private void button1_Click(object sender, EventArgs e)
{
string script = textBox1.Text;
var JSEngine = new Engine()
// Expose the alert function in JavaScript that triggers the native function (previously created) Alert
.SetValue("alert", new Action(Alert))
;
try
{
JSEngine.Execute(script);
}
catch (Jint.Runtime.JavaScriptException Ex)
{
Console.WriteLine(Ex.Message);
}
}
}
}

Обратите внимание, что мы не привязываем напрямую класс MessageBox WinForms, а настраиваемую функцию Alert. Сценарий для выполнения, который позволит вам проверить, правильно ли выставлена ​​функция оповещения, будет:

alert("Hello C# with JavaScript");

И его выполнение в форме примера будет:

Тем не менее, вы не ограничены в передаче одного аргумента. Вы можете отправлять много аргументов, если хотите, если они объявлены в вашей нативной привязке. Вам необходимо указать их в качестве аргументов в классе Action с соответствующим типом (string, int и т. Д.), Например:

private void NativeFunction(string Argument1, int Argument2)
{
// "Value of argument 1"
Console.WriteLine(Argument1);
// 99999
Console.WriteLine(Argument2);
}
string JavaScriptToExecute = @"
theNameOfTheFunction('Value of argument 1', 99999)
";
var JSEngine = new Engine()
// Expose the NativeFunction function in JavaScript and give it a name in JS
.SetValue("theNameOfTheFunction", new Action(NativeFunction))
;
// Run Script
JSEngine.Execute(JavaScriptToExecute);

Теперь вы можете установить собственный заголовок для функции оповещения:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// Import Jint
using Jint;
namespace Sandbox
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Alert(string Message, string Title)
{
MessageBox.Show(Message, Title, MessageBoxButtons.OK);
}
private void button1_Click(object sender, EventArgs e)
{
string script = textBox1.Text;
var JSEngine = new Engine()
.SetValue("alert", new Action(Alert))
;
try
{
JSEngine.Execute(script);
}
catch (Jint.Runtime.JavaScriptException Ex)
{
Console.WriteLine(Ex.Message);
}
}
}
}

Выполнение скрипта должно генерировать что-то вроде:

setValue Функция также может использоваться для представления констант из переменных в вашем коде C #.

Заметка

Если какой-либо аргумент в нативной функции не предоставлен, вы получите в качестве замены простую строку, а именно "Error",

Разрешить доступ к классам и сборкам .NET

Вы можете разрешить обработчику доступ к любому классу .NET, настроив экземпляр обработчика, как показано в следующем примере:

Engine JSEngine = new Engine(cfg => cfg.AllowClr());
try
{
JSEngine.Execute("some script string here !!");
}
catch (Jint.Runtime.JavaScriptException Ex)
{
Console.WriteLine(Ex.Message);
}

Это означает, что вы можете написать JavaScript, который использует встроенные функции, хранящиеся в сборке System. Например, если вы выполняете следующий код JavaScript на вашем движке:

// 0 stands for System.Environment.SpecialFolder.Desktop
var theFilePath = System.Environment.GetFolderPath(0) + "\\custom_file.txt";
var AFile = new System.IO.StreamWriter(theFilePath);
AFile.WriteLine("First Line of file in the desktop");
AFile.WriteLine("Second Line of file in the desktop");
AFile.Close();

Вы должны иметь сейчас custom_file.txt на рабочем столе. Как было сказано в начале статьи, работа с мощью C # в написании на JavaScript.

Получить возвращаемое значение из функции JavaScript в C #

Если вам нужно извлечь какое-то значение из JavaScript в ваш код C #, вы можете положиться на GetValue Метод движка, который ожидает в качестве первого аргумента имя функции в JavaScript, которая возвращает нужное вам значение. Это в свою очередь вернуть Jint.Native.JsValue объект, который должен храниться в переменной. Чтобы вернуть значение, выполните Invoke метод ранее сохраненной переменной (вы можете отправлять значения из C # в JavaScript, однако это не требуется, поэтому вы можете просто привести функцию к Invoke()):

try
{
var FunctionAddJavascript = new Engine()
.Execute(@"
// This function return the result of the numbers.
function add(a, b) {
return a + b;
}
")
.GetValue("add")
;
var result = FunctionAddJavascript.Invoke(5, 6) ;
// 11
Console.WriteLine(result);
}
catch (Jint.Runtime.JavaScriptException Ex)
{
Console.WriteLine(Ex.Message);
}

Двигатель силы i18n и l10n

Вы можете изменить часовой пояс Engine в C #, указав его в качестве аргумента в Engine:

TimeZoneInfo PST = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var engine = new Engine(cfg => cfg.LocalTimeZone(PST));
engine.Execute("new Date().toString()"); // Mon Apr 03 2017 06:10:31 GMT-07:00
// Or other LocalTimeZone
TimeZoneInfo PST = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var engine = new Engine(cfg => cfg.LocalTimeZone(PST));
engine.Execute("new Date().toString()"); // Mon Apr 03 2017 09:10:31 GMT-04:00

Или если вы работаете с локализацией:

// Import the Globalization type
using System.Globalization;
CultureInfo FR = CultureInfo.GetCultureInfo("fr-FR");
var engine = new Engine();
engine.Execute("new Number(1.23).toString()"); // 1.23
engine.Execute("new Number(1.23).toLocaleString()"); // 1,23
Ссылка на основную публикацию
Adblock
detector