尝试以编程方式编译和执行 C# 代码

本文关键字:执行 代码 编译 方式 编程 | 更新日期: 2023-09-27 18:32:16

以下是我的代码:

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);
                }
            }
        }
    }
}
}

hi.cs 文件的内容如下:

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");
    }
}
}

这是我尝试运行此程序时遇到的错误:

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: 

尝试以编程方式编译和执行 C# 代码

我认为

这就是问题所在:

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

这个想法(我相信)是CompileAssemblyFromSource不采用单独的行 - 数组中的每个字符串都是一个完整的 C# 源文件。所以你可能只需要

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

请注意,即使您的第一个块做了正确的事情,您仍然会无缘无故地创建一个字符串数组 - 将其编写为:

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

你不需要把你的代码拆分成这样的数组。

该数组用于传递多个源文件。

你可以尝试制作这样的代码

                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" }));
                }

它在我的代码中没有任何错误的情况下工作