4

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: 
Fox32
  • 13,126
  • 9
  • 50
  • 71
Tom
  • 411
  • 12
  • 28
  • Why are you splitting the source code in multiple strings? – MiMo Apr 25 '12 at 11:44
  • It took almost 90 to 100 milliseconds to compile and execute the method on my machine. If you are trying to dynamically push in functionality in the existing code execution, you could also use MEF. Would be better option than using core Reflection and compiler process. – Jsinh Apr 25 '12 at 12:46
  • possible duplicate of [Generating DLL assembly dynamically at run time](http://stackoverflow.com/questions/604501/generating-dll-assembly-dynamically-at-run-time) – Ruben Bartelink May 10 '13 at 12:22

3 Answers3

9

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);
Pang
  • 9,564
  • 146
  • 81
  • 122
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

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

The array is for passing multiple source files.

Pang
  • 9,564
  • 146
  • 81
  • 122
Mesh
  • 6,262
  • 5
  • 34
  • 53
1

you can try to make code like this

                string content = File.ReadAllText(@Path.GetDirectoryName(Application.ExecutablePath) + "\\r.cs");

                char[] seperators = { '\n', '\r', '\t' };
                string[] code = content.Split(seperators);

                CompilerParameters CompilerParams = new CompilerParameters();
                string outputDirectory = Directory.GetCurrentDirectory();

                CompilerParams.GenerateInMemory = true;
                CompilerParams.TreatWarningsAsErrors = false;
                CompilerParams.GenerateExecutable = false;
                CompilerParams.CompilerOptions = "/optimize";
                CompilerParams.GenerateExecutable = false;
                CompilerParams.OutputAssembly = "r.dll";
                FileStream fileStream = File.Open(Path.GetDirectoryName(Application.ExecutablePath) + "\\Output\\r.dll",FileMode.Open);
                string references =  fileStream.Name;




                CompilerParams.ReferencedAssemblies.Add(references);
                fileStream.Close();
                CSharpCodeProvider provider = new CSharpCodeProvider();
                CompilerResults compile = provider.CompileAssemblyFromFile(CompilerParams, Path.GetDirectoryName(Application.ExecutablePath) + "\\r.cs");

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

                Module module = compile.CompiledAssembly.GetModules()[0];
                Type mt = null;
                MethodInfo methInfo = null;
                MemberInfo[] memberInfo;
                //var dll = Assembly.LoadFile(references);

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

                if (mt != null)
                {
                    memberInfo = mt.GetMembers();
                    methInfo = mt.GetMethod("main");
                }

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

                }

and it is working without any error in my code