Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


#ActualRobTheBloke

Posted 11 October 2013 - 05:21 AM

Sounds a lot like a thread I wrote ages ago? Would you be looking for this:

http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/CSPluginExample2.zip

 

I actually ported that to the latest .NET framework the other day. The code more or less still works (although I had to create new project files because for some unknown reason I couldn't get the project files to upgrade successfully - and couldn't be bothered to find out why). If you want to avoid the compiler warnings, modify the code like so:

 


    public static bool ExecuteVB(string source)
    {
        VBCodeProvider prov = new VBCodeProvider();
        return ExecuteScript(prov, source);
    }

    public static bool ExecuteCS(string source)
    {
        CSharpCodeProvider prov = new CSharpCodeProvider();
        return ExecuteScript(prov, source);
    }
 
    private static bool ExecuteScript(CodeDomProvider compiler, string code)
    {
        CompilerParameters cp = new CompilerParameters();
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
 
        //
        // add any default libs you want to expose to the scripting API
        //
        cp.ReferencedAssemblies.Add("system.dll");
        cp.ReferencedAssemblies.Add("system.data.dll");
        cp.ReferencedAssemblies.Add("system.drawing.dll");
        cp.ReferencedAssemblies.Add("system.windows.forms.dll");
 
        //
        // add reference to the core dll(s) of the application. The scripts
        // will then be able to access the core functionality of the APP.
        //
        cp.ReferencedAssemblies.Add("CoreAPI.dll");
 
        CompilerResults cr;
        cr = compiler.CompileAssemblyFromSource(cp, code);
 
        // check for any errors in the script
        if (cr.Errors.HasErrors)
        {
            StringBuilder sbErr;
            sbErr = new StringBuilder();
            foreach (CompilerError err in cr.Errors)
            {
                sbErr.AppendFormat("{0} at line {1} column {2} ",
                     err.ErrorText,
                     err.Line,
                     err.Column);
                sbErr.Append("\n");
            }
            MessageBox.Show(sbErr.ToString(), "Script - Error");
            return false;
        }
 
        // get the assembly code generated
        Assembly a = cr.CompiledAssembly;
        try
        {
            return InvokeAssembly(a);
        }
        catch (Exception ex)
        {
            // this is called if an error gets generated when running the script
            MessageBox.Show(ex.Message);
        }
        return false;
    }

The basic premise is that you define the base types in the API.dll, load the plugin assembly, and then use reflection to hunt for any classes in the plugin that support any of your supported interfaces. It's probably easier to do this with interfaces rather than base classes!

 

\edit

 

Found the original thread: http://www.gamedev.net/topic/473195-saveload-as-plugin/


#1RobTheBloke

Posted 11 October 2013 - 05:18 AM

Sounds a lot like a thread I wrote ages ago? Would you be looking for this:

http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/CSPluginExample2.zip

 

I actually ported that to the latest .NET framework the other day. The code more or less still works (although I had to create new project files because for some unknown reason I couldn't get the project files to upgrade successfully - and couldn't be bothered to find out why). If you want to avoid the compiler warnings, modify the code like so:

 


    public static bool ExecuteVB(string source)
    {
        VBCodeProvider prov = new VBCodeProvider();
        return ExecuteScript(prov, source);
    }

    public static bool ExecuteCS(string source)
    {
        CSharpCodeProvider prov = new CSharpCodeProvider();
        return ExecuteScript(prov, source);
    }
 
    private static bool ExecuteScript(CodeDomProvider compiler, string code)
    {
        CompilerParameters cp = new CompilerParameters();
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
 
        //
        // add any default libs you want to expose to the scripting API
        //
        cp.ReferencedAssemblies.Add("system.dll");
        cp.ReferencedAssemblies.Add("system.data.dll");
        cp.ReferencedAssemblies.Add("system.drawing.dll");
        cp.ReferencedAssemblies.Add("system.windows.forms.dll");
 
        //
        // add reference to the core dll(s) of the application. The scripts
        // will then be able to access the core functionality of the APP.
        //
        cp.ReferencedAssemblies.Add("CoreAPI.dll");
 
        CompilerResults cr;
        cr = compiler.CompileAssemblyFromSource(cp, code);
 
        // check for any errors in the script
        if (cr.Errors.HasErrors)
        {
            StringBuilder sbErr;
            sbErr = new StringBuilder();
            foreach (CompilerError err in cr.Errors)
            {
                sbErr.AppendFormat("{0} at line {1} column {2} ",
                     err.ErrorText,
                     err.Line,
                     err.Column);
                sbErr.Append("\n");
            }
            MessageBox.Show(sbErr.ToString(), "Script - Error");
            return false;
        }
 
        // get the assembly code generated
        Assembly a = cr.CompiledAssembly;
        try
        {
            return InvokeAssembly(a);
        }
        catch (Exception ex)
        {
            // this is called if an error gets generated when running the script
            MessageBox.Show(ex.Message);
        }
        return false;
    }

The basic premise is that you define the base types in the API.dll, load the plugin assembly, and then use reflection to hunt for any classes in the plugin that support any of your supported interfaces. It's probably easier to do this with interfaces rather than base classes!

PARTNERS