1

I have a textbox in my program. In the textbox you can write the name of function/method you want to run as well as pass parameters. This is all parsed and via a big switch block if my case is filled I the code for that specific case, as well as passing the parameters.

But what I really want to do is to use stringbuilder to build source code and then run it!

This is an example of source code built with my stringbuilder.

 outlook outlooken = new outlook(appNwindow);

and

  outlooken.createNewEmail(scriptarray[i][1],scriptarray[i][2],
  scriptarray[i][3],scriptarray[i][4]);

Using stringbuilder to create strings is no problem at all. But how do I run them?

I have tested a lot, and managed to get everything in place but I think I'm missing something cuase my code always generates an error...

Here's my soruce code

 CodeDomProvider myCodeDomeProvider = CodeDomProvider.CreateProvider("CSharp");
 String [] referenceAssemblies = {"System.dll"};
 //  string myAssemblyName = "myAssembly.dll";
 CompilerParameters myCompilerparameters = 
 new CompilerParameters(referenceAssemblies);

        myCompilerparameters.GenerateExecutable = false;
        myCompilerparameters.GenerateInMemory = true;

  //*** Here's the sourcecode it want to compile
  string[] arr1 = new string[] { "outlook outlooken = new outlook(appNwindow);","outlooken.createNewEmail(scriptarray[i][1],scriptarray[i][2],scriptarray[i[3],scriptarray[i][4]);"};

        CompilerResults myResults = myCodeDomeProvider.CompileAssemblyFromSource(myCompilerparameters, arr1);
        string objectname = "testet";
        string method = "createNewEmail";
        object[] args = new object[2];

        args[0] = "to";
        args[1] = "CC";

        if (myResults.Errors.HasErrors)

         {
            StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
            foreach (CompilerError error in myResults.Errors)
            {
            errors.AppendFormat("Line {0},{1}\t: {2}\n",
            error.Line, error.Column, error.ErrorText);
            }

            throw new Exception(errors.ToString());
            }
            else
            {
            Assembly assem = myResults.CompiledAssembly;
            object instance = null;

            Type type = assem.GetType(objectname);
            MethodInfo miChk = type.GetMethod(method);

            if (!miChk.IsStatic)
            {
            instance = assem.CreateInstance(objectname);
            type = instance.GetType();
            }

            MethodInfo mi = type.GetMethod(method);

            mi.Invoke(instance, args);
            }

These are the errors I get when running it:

Additional information: Compiler Errors :

Line 1,1 : A namespace cannot directly contain members such as fields or methods

Line 1,25 : Expected class, delegate, enum, interface, or struct

Line 1,1 : A namespace cannot directly contain members such as fields or methods

Line 1,41 : Identifier expected

Line 1,59 : Identifier expected

Line 1,77 : Identifier expected

Line 1,95 : Identifier expected

2
  • ... also "aswell" isn't a word Commented Aug 4, 2012 at 0:46
  • Just keep in mind that if you do it this way the assembly that gets compiled here will be loaded into the current AppDomain and cannot be unloaded. If you do this over and over you will essentially have a memory leak. What you really need to do is to either do this in another AppDomain or another process. Otherwise you can attempt to use the DLR (Iron Python perhaps) or make your own Expression tree compiler. It's not trivial, this is not a well supported area of .net. Commented Aug 4, 2012 at 1:42

1 Answer 1

4

CodeDom won't compile and execute an arbitrary statement. The code you compile must be valid C# code, just as if you were doing a C# file from source.

This means you need to wrap the statement into a namespace + class, and put it within a method (could be static) in the class.

Basically, think of the input as if you were writing a normal C# file and compiling the .cs file with the compiler - you'll need the same "text" in your input.

Sign up to request clarification or add additional context in comments.

Comments

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.