CS-Script 3.20.0


Alternative compilers

Step-by-step tutorial 

The following tutorial shows how to create an assembly which can be used by the script engine to provide access to additional CLR compilers. In this tutorial you will create CSSCodeProvider.dll, which will allow the script engine to execute C#, VB and JScript scripts depending on the script file extension.

  1. By using any text editor (eg. Notepad.exe) create file CSSCodeProvider.cs, which contains the following code:
    using System;
    using System.IO;
    using System.CodeDom.Compiler;
    using Microsoft.JScript;

    public class CSSCodeProvider

        static public ICodeCompiler CreateCompiler(string sourceFile)
        {
            string errMsg = "Alternative compiler for file extension "
                            + Path.GetExtension(sourceFile) + " cannot be created.";
            try
            {
                if (Path.GetExtension(sourceFile).ToLower() == ".cs")
                    return (new Microsoft.CSharp.CSharpCodeProvider()).CreateCompiler();
                else if (Path.GetExtension(sourceFile).ToLower() == ".vb"
                    return (new Microsoft.VisualBasic.VBCodeProvider()).CreateCompiler();
                else if (Path.GetExtension(sourceFile).ToLower() == ".js"
                    return (new Microsoft.JScript.JScriptCodeProvider()).CreateCompiler();
            }
            catch (Exception ex)
            {
                throw new Exception(errMsg, ex);
            }
            throw new Exception(errMsg); 
        }
    }
     
  2. Open command prompt. Make sure the current directory is the directory where CSSCodeProvider.cs located. 
  3. Execute the following command in command-prompt:
    cscs /cd CSSCodeProvider

    This command will create CSSCodeProvider.dll

  4. Use Config console to instruct the script engine to use CSSCodeProvider.dll for creation of the alternative compiler. 
  5. By using any text editor (eg. Notepad.exe) create file hello.vb, which contains the following code:
    ' //css_reference System.dll;
    ' //css_reference System.Windows.Forms.dll;
    Imports System
    Imports System.Windows.Forms

    Module Module1
        Sub Main()
            Console.WriteLine("Hello World! (VB)")
            MessageBox.Show("Hello World! (VB)")
        End Sub
    End M
    
      
  6. Execute the following command in command-prompt:
    cscs hello.vb

Output 

The script will print in command prompt "Hello World! (VB)". It will also display a corresponding MessageBox.


Code discussion

CSSCodeProvider can create and return an instance of either C#, VB or JScript compiler. Why these compilers? The answer is very simple: these three compilers are guaranteed to be available on any PC with .NET runtime installed. However, if on a particular PC the other CLR compilers are installed (C++, Delphi...), they can also be used with CS-Script.  You would only need to modify the code of CSSCodeProvider.cs and compile it again. 

In fact, it does not have to be an existing compiler. You can implement any compiler by yourself if you wish. Any compilers can be used with CS-Script as long as they support  ICodeCompiler interface.

Note that System.dll and System.Windows.Forms.dll are referenced with //css_reference statement directly from the code. Because automatic assembly loading is not available for non-C# scripts (see Alternative Compilers for limitation details). 

The same approach can be used to execute the J#/JScript "Hello world!" script. The command in command-prompt in this case will look as follows:

cscs hello.js

Where hello.js file contains the following code:


//css_reference System.dll;
//css_reference System.Windows.Forms.dll;
import System;
import System.Windows.Forms;

public class Class1 {
    public static function Main() {
        Console.WriteLine("Hello World! (JScript)");
            MessageBox.Show("Hello World! (JScript)")
    }
}

Note that the custom (alternative) compiler described in this tutorial is not  very useful for the hosting scenarios.  The first reason is that the compiler is implemented as a separate assembly and it means that it has to be deployed separatelly from the script engine and the host application itself. The second reason is more important: the compiler relies on the file extension (e.g. *.vb) in order to make the decision on the script syntax. This is a problem as hosted script may not have a file but be just an in-memory code. In this case the custom compiler can be implemented in the host application. And it can be as simple as a single instanmtiation statement for the corresponding third-party compiler. The example of such a compiler for VB.NET syntax can be found in the samples folder: <cs-script>\Samples\Hosting\HostVBScript.cs.

VB.NET compiler implementation in the host application:

public class CSSCodeProvider
{
   
public static ICodeCompiler CreateCompiler(string sourceFile)
    {
       
return new Microsoft.VisualBasic.VBCodeProvider().CreateCompiler();
    }
}


Using the host-compiler:

public interface IScript
{
    void Main();
}
...
//indicate that the CS-Script engine should use custom (VB.NET) compiler
CSScript.GlobalSettings.UseAlternativeCompiler = Assembly.GetExecutingAssembly().Location;
...
string code = @"Imports System
                Imports System.Windows.Forms

                Public Class Script
                    Public Sub Main()
                        MessageBox.Show(""Hello World!"")
                    End Sub
                End Class"
;


IScript script = CSScript.LoadCode(code)
                         .CreateObject(
"Script"")
                         .AlignToInterface<
IScript>();      

script.Main();


 

See Also

Alternative Compilers | Command-line interface