C# and Visual Basic Script execution
The basic script execution workflow requires setting a script source, adding references to the assemblies used in the script; registering application-defined objects accessible to the script; compiling the script to a dynamically-linked library or standalone executable program, and running some method in that DLL or executing the program.
Setting up Script Source
All properties and methods required to set a script source are encapsulated in ScriptSource property of the ScriptRun class; below are the essential ones:
Files - specifies a collection of source files to be compiled and executed;
ScriptCode - specifies source in a form of text string;
ProjectName, ProjectFileName and RootNamespace - contain project-related information if ScriptSource is loaded from the project.
Imports - contains global namespaces in case Visual Basic is used, so you do not need to specify them in the code;
Conditionals - contains lists conditional compilation symbols;
References - contains a list of assembly references for types used in the scripts; this can include reference to the calling application.
SearchPaths - contains search paths to look for the third-party references in case they're not supplied with a full path.
Resources - contains a list of RESX files with resources.
FromScriptFile - loads Script Source from the single source file;
FromScriptCode - loads script from code in the form of a text string;
FromExpression - sets ScriptSource to the string expression.
FromScriptProject - loads code from Visual Studio Project
Adding assembly references:
The assemblies where these types are declared need to be referenced so that the script can use their types.
The following code populates references with the most commonly used assemblies:
scriptRun1.ScriptSource.WithDefaultReferences();
For technology set to WinForms, it contains the following assemblies:
System,System.Drawing System.WindowsForms;
Note that this list is different in the case of .NET Core targets.
You can reference additional assemblies by adding them to the References property:
scriptRun1.ScriptSource.References.Add("System.Data");
This method accepts a full path; you can also add references to third-party assemblies if the script uses types from it.
Registering objects to be used in the script
Application objects accessible by the script need to be added to the GlobalItems collection, along with the object's name, which will be used in the script, and the object's type or the object itself.
Object value itself is only required during script execution; for script compilation, object name and type are sufficient.
ScriptRun adds references to the assemblies, which contain types of the objects being added to GlobalItems automatically.
Note that AssemblyKind property needs to be set to Dynamically Linked Library for it to be loaded in the running application process and be able to access application-defined objects.
Below is a sample code that registers application-defined objects in the script.
public class MyItem
{
public MyItem(string text)
{
this.Text = text;
}
public string Text;
}
scriptRun1.GlobalItems.Add(new ScriptGlobalItem("MyItem", obj: new MyItem("hello")))
Script Compilation and Execution
Once ScriptSource is set, next step is to Compile the script; this step is performed implicitly when the script runs the first time or when the Script source is changed (this includes changes of script files externally)
Script compilation engine is implemented by IScriptHost; there are two implementations of IScriptHost provided: a legacy engine based on CodeDOMScriptHost wrapper around command-line C# or Visual Basic compiler, and RoslynScriptHost based on new Microsoft Roslyn Code compiler technology - the last one is used by default, and it allows some additional features such as referencing to another script source dynamically by using #load directive and gives more control on code parsing and compilation.
Scripts can be compiled into a dynamically-linked library or in a standalone executable; this is controlled by the AssemblyKind property. GenerateModulesOnDisk allows to control whether the assembly being compiled will reside in memory or on the disk; and ModulesDirectoryPath specifies the location of compiled assembly where compiled modules will be stored. Platform target (AnyCPU, AnyCpu32BitPreferred, x86, x64, or Auto) is controlled by Platform property (by default, it's set to Auto and takes the target platform from the application).
Once the compilation is executed, the Compiled property will be set to true in case compilation was successful, and IScriptHost's ScriptAssembly property will point to the assembly compiled from the script source. Otherwise IScriptHost's properties CompileFailed will be set to true and CompilerErrors will be populated with compiler errors. Please note, CompilerErrors may contain compiler warnings even in case of successful compilation.
Upon successful compilation, you can subsequently call Run, RunMethod, or their asynchronous variants: RunAsync and RunMethodAsync; in case of standalone executable RunProcess should be used instead.