Scripting is the past Native code is the future! Part 3 of 3

Download project files here ScriptingInterface.zip (11.40 kb)

This new scripting application is based on the previous examples but has been rewritten with the fallowing changes ...

  1. The application now loads and compiles the script from a file.
  2. The script now implements a interface called ICommunications. This interface is located in the host application and is used to pass messages back and fourth between the script and the host application without the need to use reflection.

The code is pretty self explanatory and easy enough to read through and understand.  

Sample Code

'Created by: X
'Copyright: Created by: X
'Web: http://www.createdbyx.com/
'Date: January 28, 2004
'=============================================
 
Public Interface ICommunications
    Sub SendMessage(ByVal Msg As Integer, _
        ByVal Params As Collections.Specialized.StringCollection)
    Sub SetMessageOutput(ByVal MO As MessageSend)
    Sub TestIt()
    Delegate Sub MessageSend(ByVal Msg As Integer, _
        ByVal Params As Collections.Specialized.StringCollection)
End Interface
 
Public Module General
    Public Sub Main()
        Dim Assm As System.Reflection.Assembly
 
        ' now compile the script using codedom
        Console.Write("Compiling script ...")
        Assm = CompileScript()
        If Not Assm Is Nothing Then
 
            Console.Write(" Done.")
            Console.WriteLine()
 
            Console.WriteLine("Running script ...")
            Console.WriteLine("---------------------------------------------------------")
 
            ' we try to create the obj rather than getting it's type reference
            Dim Obj As Object = Assm.CreateInstance("Test", True)
            ' check if the object implements the ICommunications interface
            If TypeOf Obj Is ICommunications Then
                Dim IObj As ICommunications = Obj
                Dim P As New Collections.Specialized.StringCollection()
 
                ' send a message to the script
                P.Add("ParamA")
                P.Add("ParamB")
                P.Add("ParamC")
                IObj.SendMessage(6, P)
 
                ' Give the script a method to call. Try commenting this line out to see what happens!
                IObj.SetMessageOutput(AddressOf RecieveMessages)
 
                ' Call the TestIt method
                IObj.TestIt()
            Else
                Console.WriteLine("ERROR: Test class does not implement ICommunications interface.")
            End If
        End If
 
        Console.WriteLine()
        Console.WriteLine("---------------------------------------------------------")
        Console.WriteLine("Press enter to quit...")
        Console.ReadLine()
    End Sub
 
    Public Sub RecieveMessages(ByVal Msg As Integer, _
        ByVal Params As Collections.Specialized.StringCollection)
        Dim idx As Integer
        Console.WriteLine("Scripting Host: Message recieved. MSG: " & Msg.ToString & _
                          " - Param count: " & Params.Count.ToString)
        For idx = 0 To Params.Count - 1
            Console.WriteLine("Param " & idx.ToString & ": " & Params(idx))
        Next
        Console.WriteLine()
    End Sub
 
    Public Function CompileScript() As Reflection.Assembly
        Dim CodeP As New Microsoft.VisualBasic.VBCodeProvider()
        Dim Com As CodeDom.Compiler.ICodeCompiler
        Dim Param As New CodeDom.Compiler.CompilerParameters()
        Dim Ret As CodeDom.Compiler.CompilerResults
 
 
        ' we do not want to generate a file
        Param.GenerateExecutable = False
        Param.GenerateInMemory = True
 
        ' get a reference to the compiler
        Com = CodeP.CreateCompiler()
 
        ' Add the System.dll assembly so that the compiled script can
        ' write out to the console.
        Param.ReferencedAssemblies.Add("System.dll")
        ' We also need to add the host application because that is 
        ' where the ICommunications interface is.
        Param.ReferencedAssemblies.Add("Scripting.exe")
 
        ' Now we compile the script.
        Ret = Com.CompileAssemblyFromFile(Param, "..\Script.vb")
 
        ' If there were errors during compile tell user.
        If Ret.Errors.HasErrors Then
            Console.WriteLine()
            Console.WriteLine()
            Console.WriteLine(Ret.Errors.Item(0).ErrorText)
            Return Nothing
        End If
 
        Return Ret.CompiledAssembly
    End Function
End Module 

 

Sample Script Code

'Created by: X
'Copyright: Created by: X
'Web: http://www.createdbyx.com/
'Date: February 4, 2004
'=============================================
 
Imports System
 
Public Class Test
    Implements Scripting.ICommunications
    Private mobjMO As Scripting.ICommunications.MessageSend
 
    Public Sub TestIt() Implements Scripting.ICommunications.TestIt
        If Not mobjMO Is Nothing Then
            Dim P As New Collections.Specialized.StringCollection()
            P.Add("Param1")
            P.Add("Param2")
            mobjMO(10, P)
        Else
            Console.WriteLine("Test class: No message output delegate has been setup.")
        End If
    End Sub
 
    Public Sub SendMessage(ByVal Msg As Integer, _
    ByVal Params As System.Collections.Specialized.StringCollection) _
    Implements Scripting.ICommunications.SendMessage
        Dim idx As Integer
 
        Console.WriteLine("Test class: Message recieved. MSG: " & Msg.ToString & _
                          " - Param count: " & Params.Count.ToString)
        For idx = 0 To Params.Count - 1
            Console.WriteLine("Param " & idx.ToString & ": " & Params(idx))
        Next
        Console.WriteLine()
    End Sub
 
    Public Sub SetMessageOutput(ByVal MO As Scripting.ICommunications.MessageSend) _
    Implements Scripting.ICommunications.SetMessageOutput
        mobjMO = MO
    End Sub
End Class

 

Created by: X

Just another personal website in this crazy online world

Name of author Dean Lunz (aka Created by: X)
Computer programming nerd, and tech geek.
About Me -- Resume