3

Is it event possible to import text as code, then add it in a sub in vb.net? If I have a .txt file filled with code can I import it programatically (by a button)?

What I need is to make vb.net to accept that script (txt file), and use it to declare variables and make functions/subs - that's all I need to.

11
  • 1
    You might be able to do it using Eval() but I don't think so. Commented Feb 5, 2013 at 14:11
  • 1
    It is possible to dynamically compile an assembly using the CodeDom stuff. It's somewhat easy to do, for those who have a decent grasp of .NET, but it should always be done sparingly. Typically there is a better way of doing what you need to do. Why do you think you need to do it? Commented Feb 5, 2013 at 14:12
  • For an example of what I mean by using CodeDom, take a look at my answer to this question: stackoverflow.com/a/10948013/1359668. It's in C#, but it should give you the idea of what I'm talking about. Commented Feb 5, 2013 at 14:23
  • 2
    I'm a little confused by what you are trying to do. Could you explain it further? Commented Feb 5, 2013 at 14:54
  • 2
    As @StevenDoggart pointed out, it would be better if you described the need for such behavior. There are many issues with this approach, and there is most likely a better way to do what you want. But we cannot help you further without more details from you. Commented Feb 5, 2013 at 14:56

1 Answer 1

3

You can do this kind of thing using the CodeDom objects. The CodeDom objects allow you to dynamically generate assemblies at run-time. For instance, if you make an interface

Public Interface IScript
    Property Variable1 As String
    Sub DoWork()
End Interface

Then, you create a method, like this:

Imports Microsoft.VisualBasic
Imports System.CodeDom.Compiler

' ...

Public Function GenerateScript(code As String) As IScript
    Using provider As New VBCodeProvider()
        Dim parameters As New CompilerParameters()
        parameters.GenerateInMemory = True
        parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
        Dim interfaceNamespace As String = GetType(IScript).Namespace
        Dim codeArray() As String = New String() {"Imports " & interfaceNamespace & Environment.NewLine & code}
        Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeArray)
        If results.Errors.HasErrors Then
            Throw New Exception("Failed to compile script")
        Else
            Return CType(results.CompiledAssembly.CreateInstance("Script"), IScript)
        End If
    End Using
End Function

Now, you can call it like this:

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim builder As New StringBuilder()
    builder.AppendLine("Public Class Script")
    builder.AppendLine("    Implements IScript")
    builder.AppendLine("    Public Property Variable1 As String Implements IScript.Variable1")
    builder.AppendLine("    Public Sub DoWork() Implements IScript.DoWork")
    builder.AppendLine("        Variable1 = ""Hello World""")
    builder.AppendLine("    End Sub")
    builder.AppendLine("End Class")
    Dim script As IScript = GenerateScript(builder.ToString())
    script.DoWork()
    MessageBox.Show(script.Variable1) ' Displays "Hello World"
End Sub

Obviously, instead of building the code in a string builder, you could load it out of a text file, like this:

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim script As IScript = GenerateScript(File.ReadAllText("C:\script.txt")
    script.DoWork()
    MessageBox.Show(script.Variable1) ' Displays "Hello World"
End Sub
Sign up to request clarification or add additional context in comments.

4 Comments

when I use script.DoWork() what happens exactly? P.S: Sorry for being "snippy", I was a bit nervous so...hope you don't care about that and reply to my question :)
No hard feelings, I know how it goes :) Anyway, when you call script.DoWork, it calls the Script.DoWork method that is defined in the string builder. In my example, all it does is set the value of the Variable1 property to "Hello World". But it could do anything you want--that's the beauty of it being a script :)
So it executes the code right? But how do I declare a variable (or a global one)? It's optional, but it's for my general knowledge
Yes, calling the DoWork method executes the code in the DoWork method, just as if it was defined locally in your own pre-compiled assembly. I just showed that IScript interface as an example. You could have as many methods and properties defined in that interface as you need. The Variable1 property was my attempt at demonstrating how to declare a variable, as you mentioned, with a script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.