好吧,我首先会承认我对所有这些都不了解正确的术语,因此,如果已经解决了这个问题,并且我没有使用适当的词语,我深表歉意.
我正在尝试使用C#编写程序,以允许该程序编译的C#代码充当脚本语言.
这是我的示例代码,用于加载和编译代码的程序:
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace RuntimeCompilation
{
public class Program
{
public static void Main(string[] args)
{
Program b = new Program();
CompilerResults results = b.BuildAssembly("Class1.cs"); // compiles the class
if (results.Errors.Count > 0)
{
System.Console.Out.WriteLine("Errors Follow:");
String ErrorText = "";
foreach (CompilerError CompErr in results.Errors)
{
ErrorText = ErrorText +
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
System.Console.Out.WriteLine(ErrorText);
}
else
{
Assembly assembly = results.CompiledAssembly;
foreach (Type type in assembly.GetTypes())
{
System.Console.WriteLine("Type found: " + type.FullName);
System.Console.WriteLine("Creating Instance:");
System.Console.WriteLine("=======================");
assembly.CreateInstance(type.FullName);
System.Console.Out.WriteLine("=======================");
System.Console.Out.WriteLine("Done");
}
}
System.Console.Out.WriteLine("DONE.");
}
// Compile a file of source and return the CompilerResults object.
private CompilerResults BuildAssembly(string filename)
{
TextReader tr = new StreamReader(filename);
string code = tr.ReadToEnd();
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = true;
return provider.CompileAssemblyFromSource(compilerparams, code);
}
public bool iCanHasAccess()
{
return true;
}
}
}
这是它构建的类:
using System;
using RuntimeCompilation;
namespace RuntimeCompilation
{
public class Class1
{
public Class1()
{
System.Console.WriteLine("This was instancialized");
if (Program.iCanHasAccess())
System.Console.WriteLine("I have access");
}
}
}
程序输出的错误是名称“程序”在当前上下文中不存在.如何确保“脚本”程序可以访问编译程序的功能和成员?
我正在尝试以最小的运行时开销允许一种简单的方法,使用户无需重新构建即可修改程序中组件的行为.如果通过C#程序集无法做到这一点,我可能会使用LUA,但我希望避免使用它.正如我希望该产品在XBox360上运行一样,必须在通过XNA部署之前将WHOLE项目和脚本一起编译.
解决方法:
您需要对当前程序集的引用,例如:
compilerparams.ReferencedAssemblies.Add("my.dll"); // or .exe
但是-以下仍然会失败:
if (Program.iCanHasAccess())
System.Console.WriteLine("I have access");
因为iCanHasAccess()是实例方法,而不是静态方法.