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
javascript|vbscript| Script

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. PropertyAllowui 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 details about the last error that occurred. Read-only. Language property: Sets or returns the name of the Script language 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 the execution of the Script code or allow the code to continue executing. can read and write. Usesafesubset property: Sets or returns a Boolean value indicating whether the host application has confidentiality requirements. If the host application requires security control, the Usesafesubset is True or False. can read and write. MethodAddcode 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. Add a few the Allowui property if set to false, statements such as dialog boxes do not work, such as MsgBox statements in VBScript, alert in JavaScript, etc. And if you execute a script that exceeds the number of milliseconds that the timeout set, it does not jump out of the dialog box that exceeds the time reminder, or vice versa; The reset Language property clears the Addcode-loaded code, and when the Timeout property occurs, the timeout is ScriptControl Examine the Allowui property of the object to determine 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;        //define script run timeout event           Public EvenT Runtimeouthandler runtimeout;        ///<summary>         ///Constructor         ///</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 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 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 Run method          ///</summary>        ///<param Name= "Mainfunctionname" >Port function name </param>        ///<param name= "parameters" > Parameter </ 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 Run method         ///</SUMMARY>    &Nbsp;   ///<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 ScriptControl         ///</summary>          public void Reset ()          {               This.msc.Reset ();         }        ///<summary>         ///Get or set script 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>        ///settings Display user interface elements    &NBsp;    ///</summary>         public bool allowui         {               Get{return This.msc.AllowUI;}               Set{this.msc.allowui = value;}         }        ///< summary>        ///host applications have 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 wrapper above 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)      & nbsp;   {              if (disposing)                    if (Components!= null)                         comPonents. Dispose ();              base. Dispose (disposing);        }          #region The code generated by the Windows forms Designer          private void InitializeComponent ()          {              //ellipsis         }          #endregion           [stathread]          static void Main ()          {               Application.Run (New Form1 ());         }        //Run scripts           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 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!");         }    }}


below is the test program run interface:


wrote a JavaScript function in the text box. Enter , output 12000012 . If the timeout is adjusted to 1 milliseconds, executing the script jumps out of the following timeout reminder box and fires the event.


Summary, the above demo JavaScript script, if interested readers can write some vbsript functions to test, the scripting language is listed only three kinds, see Help, he also supports some other scripts, if necessary can add. In addition, because it is called COM, some return values are OBEJCT types and need to be converted. CSDN in the Technical Forum under the C # section often have friends to ask this question, for those who encounter such problems, hope that through this article can get some of the help you need, very happy to do with. NET friend Exchange, my email address zhzuocn@163.com





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.