Invoke the implementation of scripts such as VBScript, JavaScript, and so on in C #

Source: Internet
Author: User
Tags define bool eval execution expression object model reference tostring
vbscript| scripts Call VBScript, JavaScript, and so on in C # implementations

Author: Autumn Maple

Previously in the work Flow (workflow) project, one of them is that when a user makes a process definition, it is possible to write a script to control the jump of the activity, and after these scripts are defined, the workflow engine controls the sequence of activity execution when the process is started, and the two activities of the string type are simpler, But some activities to the next activity conditional judgment, or there are multiple branches, simple fortunately, as long as in the database table to add a field can be implemented, a complex point needs to be implemented through the script. There was not enough experience, a few days did not find a quick solution, want to write a custom script engine is not sure, and time is not enough, or look for it on the internet, spent some time, or found a better solution, write to share with you.
Here are two parts to illustrate implementation and application.


A Using Msscriptcontrol

Download Windows Script control to Microsoft's Web site, which is an ActiveX (R) controls, so in. NET use me to interop a bit. After the download installation completes, create a new C # Windows Application project, select the reference node in Solution Explorer, right-click the Add Reference menu, pop up the Add Reference dialog box, click Browse to find the directory where Windows Script control is installed. Select MSScript.ocx file to determine. Then a Msscriptcontrol component is added under the reference node, and the following is all the objects after his interop.




ScriptControl provides a simple interface to the host script engine that supports ActiveX (TM) script. Next we explain the properties and methods of the ScriptControl that are converted into Scriptcontrolclass classes.

Property

Allowui property: The user interface element that is applied to the ScriptControl itself or the SCIRPT engine is readable and writable.

CodeObject property: Returns an object that is used to invoke the public members of the specified module. Read-only.

Error property: Returns an Error object that contains detailed information about the last error that occurred. Read-only.

Language Property: Sets or returns the name of the Script language that is being used. can read and write.

Modules property: Returns a collection of modules for the ScriptControl object. Read-only.

Procedures property: Returns a collection of procedures defined in the specified module. Read-only.

Sitehwnd Property: Sets or returns the HWnd of the window, which is used to display dialog boxes and other user interface elements by executing the Script code. can read and write.

State property: Sets or returns the pattern of the ScriptControl object. can read and write.

Timeout Property: Sets or returns the time (in milliseconds) after which the user can choose to abort execution of the Script code or allow the code to continue execution. can read and write.

Usesafesubset Property: Sets or returns a Boolean value indicating whether the host application has a confidentiality requirement. If the host application requires security control, the Usesafesubset is True or False. can read and write.

Method

Addcode method: Adds the specified code to the module. You can call the Addcode method multiple times.

AddObject method: Make the Host object model available to the Script engine.

Eval method: Evaluates an expression and returns the result.

Executestatement method: Executes the specified statement.

Reset method: Discard all Script code and objects that have been added to the ScriptControl.

Run method: Runs the specified procedure.

Event

Error Event: This event occurs when a run-time error occurs.

Timeout Event: This event occurs when the time specified by the Timeout property is exceeded and the user selects end in the Results dialog box.

Additional points

Allowui property If set to false, statements such as a dialog box do not work, such as MsgBox statements in VBScript, alert in JavaScript, and if the script that executes exceeds the number of milliseconds set by timeout. Also does not jump out of time reminders of the dialog box, vice versa; Reset the Language property clears the Addcode-loaded code; For the Timeout property, the ScriptControl examines the object's Allowui properties when a timeout occurs. Determines whether user interface elements are allowed to be displayed.

If the reader needs a more detailed understanding, you can view the MSDN documentation.

To make the control easier to use, I wrapped it in a scriptengine class, and here's the complete code:


Using System;

Using Msscriptcontrol;

Using System.Text;

Namespace ZZ

{

<summary>

Script type

</summary>

public enum ScriptLanguage

{

<summary>

JScript scripting language

</summary>

Jscript

<summary>

VBScript scripting language

</summary>

VBscript,

<summary>

JavaScript scripting language

</summary>

Javascript

}

<summary>

Script Run Error Agent

</summary>

public delegate void Runerrorhandler ();

<summary>

Script Run Timeout agent

</summary>

public delegate void Runtimeouthandler ();

<summary>

ScriptEngine class

</summary>

public class ScriptEngine

{

Private ScriptControl MSC;

Define script Run error events

public event Runerrorhandler Runerror;

To define a script run timeout event

public event Runtimeouthandler Runtimeout;

<summary>

Constructors

</summary>

Public ScriptEngine (): This (scriptlanguage.vbscript)

{

}

<summary>

Constructors

</summary>

<param name= "Language" > Script type </param>

Public ScriptEngine (ScriptLanguage language)

{

This.msc = new Scriptcontrolclass ();

This.msc.UseSafeSubset = true;

This.msc.Language = Language. ToString ();

((dscriptcontrolsource_event) this.msc). Error + = new Dscriptcontrolsource_erroreventhandler (scriptengine_error);

((dscriptcontrolsource_event) this.msc). Timeout + = new Dscriptcontrolsource_timeouteventhandler (scriptengine_timeout);

}

<summary>

Run the Eval method

</summary>

<param name= "expression" > Expression </param>

<param name= "Codebody" > Function Body </param>

<returns> return value object</returns>

public Object Eval (String expression,string codebody)

{

MSc. Addcode (Codebody);

return MSC. Eval (expression);

}

<summary>

Run the Eval method

</summary>

<param name= "Language" > Scripting language </param>

<param name= "expression" > Expression </param>

<param name= "Codebody" > Function Body </param>

<returns> return value object</returns>

public Object Eval (scriptlanguage language,string expression,string codebody)

{

if (this. Language!= Language)

This. Language = Language;

Return Eval (Expression,codebody);

}

<summary>

Running the Run method

</summary>

<param name= "Mainfunctionname" > Entry function name </param>

<param name= "Parameters" > Parameters </param>

<param name= "Codebody" > Function Body </param>

<returns> return value object</returns>

public Object Run (string mainfunctionname,object[] parameters,string codebody)

{

This.msc.AddCode (Codebody);

return MSC. Run (mainfunctionname,ref parameters);

}

<summary>

Running the Run method

</summary>

<param name= "Language" > Scripting language </param>

<param name= "Mainfunctionname" > Entry function name </param>

<param name= "Parameters" > Parameters </param>

<param name= "Codebody" > Function Body </param>

<returns> return value object</returns>

public Object Run (scriptlanguage language,string mainfunctionname,object[] parameters,string codebody)

{

if (this. Language!= Language)

This. Language = Language;

Return Run (Mainfunctionname,parameters,codebody);

}

<summary>

Discard all Script code and objects that have been added to the ScriptControl

</summary>

public void Reset ()

{

This.msc.Reset ();

}

<summary>

Gets or sets the scripting language

</summary>

Public ScriptLanguage Language

{

Get{return (scriptlanguage) Enum.parse (typeof (ScriptLanguage), this.msc.language,false);

Set{this.msc.language = value. ToString ();}

}

<summary>

Gets or sets the execution time of the script, in milliseconds

</summary>

public int Timeout

{

Get{return This.msc.Timeout;}

Set{this.msc.timeout = value;}

}

<summary>

Set whether to display user interface elements

</summary>

public bool Allowui

{

Get{return This.msc.AllowUI;}

Set{this.msc.allowui = value;}

}

<summary>

Whether the host application has confidentiality requirements

</summary>

public bool Usesafesubset

{

Get{return This.msc.UseSafeSubset;}

Set{this.msc.usesafesubset = true;}

}

<summary>

Runerror event Excitation

</summary>

private void OnError ()

{

if (runerror!=null)

Runerror ();

}

<summary>

OnTimeOut event Excitation

</summary>

private void OnTimeOut ()

{

if (runtimeout!=null)

Runtimeout ();

}

private void Scriptengine_error ()

{

OnError ();

}

private void Scriptengine_timeout ()

{

OnTimeOut ();

}

}

}

The above wrapper defines a ScriptLanguage enumeration, which makes it easier to operate. In addition, the scripting engine includes error events and timeout events, which can be registered based on actual usage.



Two Script Engine Demo

I built a form program to test the choice of scripting language, whether to turn on the Allowui property, the timeout setting, and the script engine invocation method. The test program code is relatively long, and the main sections are listed below:

Using System;

Using System.Drawing;

Using System.Collections;

Using System.ComponentModel;

Using System.Windows.Forms;

Using System.Data;

Namespace ZZ

{

public class Form1:System.Windows.Forms.Form

{

Private ScriptEngine ScriptEngine;

Private System.Windows.Forms.CheckBox Checkboxallowui;

Private System.Windows.Forms.TextBox Textboxresult;

Private System.Windows.Forms.NumericUpDown numericupdowntimeout;

Private System.Windows.Forms.TextBox textboxcodebody;

Private System.Windows.Forms.Button Buttonrun;

Private System.Windows.Forms.Button Buttoncancel;

Private System.Windows.Forms.ComboBox Comboboxscript;

Private System.Windows.Forms.TextBox Textboxparams;

Private System.Windows.Forms.RadioButton Radiobuttoneval;

Private System.Windows.Forms.RadioButton Radiobuttonrun;

Private System.Windows.Forms.TextBox Textboxmethodname;

Private System.ComponentModel.Container components = null;



Public Form1 ()

{

InitializeComponent ();

This.comboBoxScript.SelectedIndex = 0;

This.scriptengine = new ScriptEngine ();

This.scriptEngine.UseSafeSubset = true;

This.scriptEngine.RunError + = new Runerrorhandler (scriptengine_runerror);

This.scriptEngine.RunTimeout + = new Runtimeouthandler (scriptengine_runtimeout);

}

protected override void Dispose (bool disposing)

{

if (disposing)

if (Components!= null)

Components. Dispose ();

Base. Dispose (disposing);

}

Code generated #region the Windows forms Designer

private void InitializeComponent ()

{

Omitted

}

#endregion

[STAThread]

static void Main ()

{

Application.Run (New Form1 ());

}

Run the script

private void Buttonrun_click (object sender, System.EventArgs e)

{

This.scriptEngine.Reset ();

This.scriptEngine.Language = (scriptlanguage) enum.parse (typeof (ScriptLanguage), This.comboBoxScript.SelectedItem.ToString ());

This.scriptEngine.Timeout = (int) this.numericUpDownTimeout.Value;

This.scriptEngine.AllowUI = this.checkBoxAllowUI.Checked;

if (this.radioButtonEval.Checked)//Execute Eval method

{

This.textBoxResult.Text = This.scriptEngine.Eval (this.textboxmethodname.text+ "(" +this.textboxparams.text+ ")", This.textBoxCodeBody.Text). ToString ();

}

else//Execute the Run method

{

string[] Parameters = (string[]) this.textBoxParams.Text.Split (', ');

Object [] ParamArray = new object[parameters. Length];

for (int i = 0;i<parameters. length;i++)

Paramarray[i] = Int32.Parse (Parameters[i]);

This.textBoxResult.Text = This.scriptEngine.Run (this.textboxmethodname.text,paramarray,this.textboxcodebody.text ). ToString ();

}

}

Exit program

private void Buttoncancel_click (object sender, System.EventArgs e)

{

This. Close ();

}

Error function

private void Scriptengine_runerror ()

{

MessageBox.Show ("Runerror Execute script Error!");

}

private void Scriptengine_runtimeout ()

{

MessageBox.Show ("runtimeout Execute script timeout, raise error!");

}

}

}


Here is the test program run interface:




A JavaScript function is written in the text box. Enter 12, output 12000012.

If the timeout is adjusted to 1 milliseconds, the execution of the script jumps out of the following timeout reminder box and fires the event.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.