Console.WriteLine text from CodeDomProvider

388 Views Asked by At

I'm trying to use CodeDomProvider to make a C# compiler. I managed to get the errors but i can't get the output.

This is what i have so far:

    public List<string> Errors(CompilerResults compilerResults)
    {
        List<string> messages = new List<string>();

        foreach (CompilerError error in compilerResults.Errors)
        {
            messages.Add(String.Format("Line {0} Error No:{1} - {2}", error.Line, error.ErrorNumber, error.ErrorText));
        }

        return messages;
    }

    public CompilerResults ProcessCompilation(string programText)
    {
        CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp");
        CompilerParameters parameters = new CompilerParameters();
        parameters.GenerateExecutable = false;
        StringCollection assemblies = new StringCollection();
        return codeDomProvider.CompileAssemblyFromSource(parameters, programText);
    }

CSharpCompiler is the class that contains the functions from above

    public JsonResult Compiler(string code)
    {
        CSharpCompiler compiler = new CSharpCompiler();
        CompilerResults compilerResults = compiler.ProcessCompilation(code);

        Debug.WriteLine("OUTPUT----------------------------------------------");
        foreach (var o in compilerResults.Output)
        {
            Debug.WriteLine(o);
        }

        List<string> compilerErrors = compiler.Errors(compilerResults);

        if (compilerErrors.Count != 0)
            return Json(new { success = false, errors = compilerErrors});

        return Json(true);
    }

compilerResults.Output is always empty. If i run this piece of code:

using System;

public class HelloWorld
{
    public static void Main()
    {
        Console.WriteLine("Hello world!");
    }
}

What can i do to display the message "Hello world!"?

1

There are 1 best solutions below

0
On

CompileAssemblyFromSource creates, as its name implies, an assembly. To get access to the compiled code, you can use the CompilerResults.CompiledAssembly property and then use reflection to find and invoke the Main method:

compilerResults.CompiledAssembly.GetType("HelloWorld").GetMethod("Main").Invoke(null, null);

Though if you set parameters.GenerateExecutable to true, you can simplify this to:

compilerResults.CompiledAssembly.EntryPoint.Invoke(null, null);