Newly built C# Assembly's access to predefined functions
Okay I will first admit I don't know the proper terminology for all this so I apologize if this is addressed already and I just am not using the appropriate words.
I'm trying to make a program in C# that will allow C# code compiled by the program to act as a scripting language.
Here is my example code for the program that loads and compiles the code:
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;
}
}
}
And here is the class it builds:
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");
}
}
}
The error outputted by the program is that the name Program doesn't exist in the current context. How can I ensure that the "script" program has access to the functions and members of the compiling program?
I'm tr开发者_开发知识库ying to allow an easy way with minimal runtime overhead to let users modify the behaviour of a component within the program without requiring a rebuild. If this is not possible through C# assemblies I'll likely use LUA but I'd like to avoid it. As I'd like this product to work on an XBox360 necessitating compiling the WHOLE project and scripts together before deployment through XNA.
You'll need a reference to the current assembly, i.e. something like:
compilerparams.ReferencedAssemblies.Add("my.dll"); // or .exe
however - the following will still fail:
if (Program.iCanHasAccess())
System.Console.WriteLine("I have access");
because iCanHasAccess()
is an instance method, not a static
method.
精彩评论