Website may be up and down over next few months. I'm currently doing a complete overhaul of everything. Going back to simple individual .htm pages, new overall site theme, sanitizing and cleaning up html of all pages and blog posts, attempting to implement a new tooling and publishing system etc etc.

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

The next code sample I will submit (hopefully soon) will be much more interesting, because it will demonstrate how the script and the application can communicate through an interface rather then the script having to use reflection to gain access to methods, classes and data inside of the application.

The fallowing code is based on the previous code I provided and demonstrates how a script (Code that gets compiled) Can access public variables that are contained inside of the running application. The script does this using reflection. Note that I am specifying to compile the script to memory as well as not have the compiler generate any compiled assemblies.

Simply create a new console application in vb.net and copy/paste the code below into the code window to run. The code is pretty self explanatory and easy enough to read through and understand.

'Created by: X
'Copyright: Created by: X
'Web: http://www.createdbyx.com/
'Date: January 28, 2004
'=============================================
 
Public Module General
    Public strTest As String = "Custom String"
 
    Public Sub Main()
        Dim Assm As System.Reflection.Assembly
        Dim Source As String
        Dim GenClass As Boolean = False  ' change this to False to see different output
 
        ' build script code. Normally this would be done by loading a file containing the script code.
        Console.Write("Building script ...")
        Source = BuildScript(GenClass)
        Console.Write(" Done.")
        Console.WriteLine()
 
        ' now compile the script using codedom
        Console.Write("Compiling script ...")
        Assm = CompileScript(Source)
        If Not Assm Is Nothing Then
 
            Console.Write(" Done.")
            Console.WriteLine()
 
            Console.WriteLine("Running script ...")
            Console.WriteLine("---------------------------------------------------------")
 
            If GenClass Then
                ' we create the obj rather than getting it's type reference
                Dim Obj As Object = Assm.CreateInstance("Test", True)
                Dim Meth As Reflection.MethodInfo = Obj.GetType.GetMethod("TestIt")
                'NOTE: You may need to specfy the owner of the method if the method is not declared shared.
                '      For example if System.Console.WriteLine was not a shared member you would need to 
                '      specify Meth.Invoke(obj, Nothing). For example this code will cause an error 
                '      Meth.Invoke(New CodeDom.CodeExpression(), Nothing) because the method does not belong to
                '      CodeDom.CodeExpression it belongs to Obj.
                Meth.Invoke(obj, Nothing)
 
            Else
 
                Dim Obj As Type = Assm.GetType("Test") ' get type reference for module
                Dim Meth As Reflection.MethodInfo = Obj.GetMethod("TestIt")
                'NOTE: You may need to specfy the owner of the method if the method is not declared shared.
                '      For example if System.Console.WriteLine was not a shared member you would need to 
                '      specify Meth.Invoke(obj, Nothing)
                Meth.Invoke(Nothing, Nothing)
            End If
        End If
 
        Console.WriteLine()
        Console.WriteLine("---------------------------------------------------------")
        Console.WriteLine("Press enter to quit...")
        Console.ReadLine()
    End Sub
 
    Public Function BuildScript(Optional ByVal GenerateClass As Boolean = True) As String
        Dim Source As String
 
        If GenerateClass Then
            Source = "Public Class Test" & vbCrLf
            Source &= "Public Sub TestIt()" & vbCrLf
            Source &= "System.Console.WriteLine(""Class code Worked!"")" & vbCrLf
            Source &= "End Sub" & vbCrLf
            Source &= "End Class"
        Else
            Source = "Public Module Test" & vbCrLf
            Source &= "Public Sub TestIt()" & vbCrLf
            Source &= "Dim S As String" & vbCrLf
 
            Source &= "Dim assm As System.Reflection.Assembly = System.Reflection.Assembly.GetCallingAssembly" & vbCrLf
            Source &= "System.Console.WriteLine( assm is nothing)" & vbCrLf
 
            Source &= "Dim T As System.Type" & vbCrLf
            Source &= " For Each T In assm.GetTypes()" & vbCrLf
            Source &= "System.Console.WriteLine(T.FullName)" & vbCrLf
            Source &= "Next" & vbCrLf
 
            Source &= "Dim Obj As System.Type = assm.GetType(""Scripting.General"") " & vbCrLf
            Source &= "System.Console.WriteLine( obj is nothing)" & vbCrLf
            Source &= "S = Obj.GetField(""strTest"").GetValue(Obj)" & vbCrLf
 
            Source &= "System.Console.WriteLine(""Module Code Worked! "" & S)" & vbCrLf
            Source &= "End Sub" & vbCrLf
            Source &= "End Module"
 
        End If
 
        Return Source
    End Function
 
    Public Function CompileScript(ByVal Source As String) 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")
 
        ' Nopw we compile the script.
        Ret = Com.CompileAssemblyFromSource(Param, Source)
 
        ' 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

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