Novetus_src/Novetus/NovetusCore/Classes/Script.cs

112 lines
3.6 KiB
C#

#region Usings
using System;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.IO;
using System.Linq;
#endregion
// based on https://stackoverflow.com/questions/137933/what-is-the-best-scripting-language-to-embed-in-a-c-sharp-desktop-application
namespace Novetus.Core
{
#region Script
public class Script
{
public static object LoadScriptFromContent(string scriptPath)
{
try
{
using (var stream = File.OpenRead(scriptPath))
{
using (var reader = new StreamReader(stream))
{
string script = reader.ReadToEnd();
Assembly compiled = CompileScript(script, scriptPath);
object code = ExecuteScript(compiled, scriptPath);
return code;
}
}
}
catch (Exception ex)
{
ErrorHandler(scriptPath + ": " + ex.ToString(), true);
}
return null;
}
private static object ExecuteScript(Assembly assemblyScript, string filePath)
{
if (assemblyScript == null)
{
goto error;
}
foreach (Type type in assemblyScript.GetExportedTypes())
{
if (type.IsInterface || type.IsAbstract)
continue;
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor != null && constructor.IsPublic)
{
return constructor.Invoke(null);
}
else
{
ErrorHandler(filePath + ": Constructor does not exist or it is not public.", true);
return null;
}
}
error:
ErrorHandler(filePath + ": Failed to load script.", true);
return null;
}
private static Assembly CompileScript(string code, string filePath)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters perams = new CompilerParameters();
perams.GenerateExecutable = false;
perams.GenerateInMemory = true;
var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => a.Location);
perams.ReferencedAssemblies.AddRange(assemblies.ToArray());
CompilerResults result = provider.CompileAssemblyFromSource(perams, code);
foreach (CompilerError error in result.Errors)
{
ErrorHandler(error, filePath, error.IsWarning, false);
}
if (result.Errors.HasErrors)
{
return null;
}
return result.CompiledAssembly;
}
public static void ErrorHandler(string error, bool finalError = false)
{
ErrorHandler(error, false, finalError);
}
private static void ErrorHandler(string error, bool warning, bool finalError)
{
Util.ConsolePrint(warning ? "[SCRIPT WARNING] - " : "[SCRIPT ERROR] - " + error, warning ? 5 : 2);
}
private static void ErrorHandler(CompilerError error, string fileName, bool warning, bool finalError)
{
Util.ConsolePrint(warning ? "[SCRIPT WARNING] - " : "[SCRIPT ERROR] - " + fileName + " (" + error.Line + "," + error.Column + "): " + error.ErrorText, warning ? 5 : 2);
}
}
#endregion
}