Динамическая компиляция плагинов и доступ к родительскому приложению - C#
Формулировка задачи:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
namespace LauncherCde
{
class Eval
{
public static Dictionary<string, Assembly> ClassObjects = new Dictionary<string, Assembly>();
public static void Init()
{
var this_namespace = typeof(Eval).Namespace;
if (Directory.Exists("./Plugins/"))
{
var ListFiles = Directory.GetFiles("./Plugins/");
In();
foreach (var _File in ListFiles)
{
FileInfo fi = new FileInfo(_File);
var ex = fi.Name.Split('.');
var filename = fi.Name.Remove(fi.Name.Length -3, 3);
if (ex[ex.Length - 1] == "cs")
{
var result = Run(File.ReadAllLines(_File));
if (result != null) {
Console.WriteLine("File <" + filename + "> compiling success!");
ClassObjects.Add(filename, result);
CallHook("OnLoad", filename, result);
}
}
else Console.WriteLine("File <" + filename + "> not is CSharp file!");
}
CallHook("OnPluginsLoaded");
}
}
public static void CallHook(string HookName, string ClassName, Assembly FileObject, bool Need = true)
{
object o = FileObject.CreateInstance(ClassName);
Type t = o.GetType();
MethodInfo mi = t.GetMethod(HookName);
if (mi != null)
mi.Invoke(o, null);
else
if(Need)
Console.WriteLine("Not fond method: <"+HookName+"> To plugin: " + ClassName);
}
public static void CallHook(string HookName)
{
foreach (var classobject in ClassObjects)
CallHook(HookName, classobject.Key, classobject.Value, false);
}
public static CSharpCodeProvider c = new CSharpCodeProvider();
public static ICodeCompiler icc = c.CreateCompiler();
public static CompilerParameters cp = new CompilerParameters();
public static void In()
{
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.xml.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.drawing.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
}
public static Assembly Run(string[] filecontent)
{
StringBuilder sb = new StringBuilder("");
foreach (var line in filecontent)
sb.Append(line);
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
Console.WriteLine("Error compiling: " + cr.Errors[0].ErrorText);
return null;
}
return cr.CompiledAssembly;
}
}
}Решение задачи: «Динамическая компиляция плагинов и доступ к родительскому приложению»
textual
Листинг программы
CSScript.LoadCode(File.ReadAllText(_File))