Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

trying to compile and execute C# code programmatically

Tags:

c#

The following is my code :

using System;
using System.Collections.Generic;
using System.Text;

using System.CodeDom.Compiler;
using System.IO;
using Microsoft.CSharp;
using System.Reflection;

namespace DynaCode
{

class Program
{

    static void Main(string[] args)
    {

        string content = File.ReadAllText(@"D:\hi.cs");
        string[] code = new string[content.Length];
        char[] seperators = { '\n','\r','\t' };
        code = content.Split(seperators);


        CompileAndRun(code);

        Console.ReadKey();

    }

    static void CompileAndRun(string[] code)
    {
        CompilerParameters CompilerParams = new CompilerParameters();
        string outputDirectory = Directory.GetCurrentDirectory();

        CompilerParams.GenerateInMemory = true;
        CompilerParams.TreatWarningsAsErrors = false;
        CompilerParams.GenerateExecutable = false;
        CompilerParams.CompilerOptions = "/optimize";

        string[] references = { "System.dll"};

        CompilerParams.ReferencedAssemblies.AddRange(references);

        CSharpCodeProvider provider = new CSharpCodeProvider();
        CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, code);

        if (compile.Errors.HasErrors)
        {
            string text = "Compile error: ";
            foreach (CompilerError ce in compile.Errors)
            {
                text += "rn" + ce.ToString();
            }
            throw new Exception(text);
        }

        //ExpoloreAssembly(compile.CompiledAssembly);

        Module module = compile.CompiledAssembly.GetModules()[0];
        Type mt = null;
        MethodInfo methInfo = null;

        if (module != null)
        {
            mt = module.GetType("DynaCore.DynaCore");
        }

        if (mt != null)
        {
            methInfo = mt.GetMethod("Main");
        }

        if (methInfo != null)
        {
            Console.WriteLine(methInfo.Invoke(null, new object[] { "here in dyna code" }));
        }
    }

    static void ExpoloreAssembly(Assembly assembly)
    {
        Console.WriteLine("Modules in the assembly:");
        foreach (Module m in assembly.GetModules())
        {
            Console.WriteLine("{0}", m);

            foreach (Type t in m.GetTypes())
            {
                Console.WriteLine("t{0}", t.Name);

                foreach (MethodInfo mi in t.GetMethods())
                {
                    Console.WriteLine("tt{0}", mi.Name);
                }
            }
        }
    }
}
}

The contents of the hi.cs file is as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;



namespace DynaCore
{
class DynaCore
{
    static public void Main(string[] args)
    {

     Console.WriteLine("hello, this is good");

    }
}
}

This is the error I get when I try to run this program:

System.Exception was unhandled
  Message="Compile error: rnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.16.cs(1,19) : error CS1514: { expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.16.cs(1,19) : error CS1513: } expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.18.cs(1,1) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.20.cs(1,19) : error CS1514: { expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.20.cs(1,19) : error CS1513: } expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.20.cs(1,11) : error CS0101: The namespace '<global namespace>' already contains a definition for 'DynaCore'rnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.22.cs(1,5) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.24.cs(1,23) : error CS1518: Expected class, delegate, enum, interface, or structrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.24.cs(1,40) : error CS1001: Identifier expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.24.cs(1,42) : error CS1518: Expected class, delegate, enum, interface, or structrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.26.cs(1,9) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.30.cs(1,10) : error CS0116: A namespace does not directly contain members such as fields or methodsrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.35.cs(1,9) : error CS1022: Type or namespace definition, or end-of-file expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.37.cs(1,5) : error CS1022: Type or namespace definition, or end-of-file expectedrnc:\\Documents and Settings\\simonjef\\Local Settings\\Temp\\mftbafdt.39.cs(1,1) : error CS1022: Type or namespace definition, or end-of-file expected"
  Source="Compiling"
  StackTrace:
       at DynaCode.Program.CompileAndRun(String[] code) in C:\Documents and Settings\simonjef\My Documents\Visual Studio 2008\Projects\Compiling\Compiling\Program.cs:line 72
       at DynaCode.Program.Main(String[] args) in C:\Documents and Settings\simonjef\My Documents\Visual Studio 2008\Projects\Compiling\Compiling\Program.cs:line 42
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
like image 970
Tom Avatar asked Dec 27 '22 01:12

Tom


2 Answers

I believe this is the problem:

string content = File.ReadAllText(@"D:\hi.cs");
string[] code = new string[content.Length];
char[] seperators = { '\n','\r','\t' };
code = content.Split(seperators);

The idea (I believe) is that CompileAssemblyFromSource doesn't take individual lines - each string in the array is meant to be a complete C# source file. So you probably just need:

string[] code = new[] { File.ReadAllText(@"D:\hi.cs") };

Note that even if your first block were doing the right thing, you'd still have been creating a string array for no reason - it would have been simpler to write it as:

string content = File.ReadAllText(@"D:\hi.cs");
char[] seperators = { '\n','\r','\t' };
string[] code = content.Split(seperators);
like image 92
Jon Skeet Avatar answered Dec 29 '22 16:12

Jon Skeet


You don't need to split your code into an array like that.

The array is for passing multiple source files.

like image 43
Mesh Avatar answered Dec 29 '22 15:12

Mesh