0

I need to compile some code dynamically in my Winform application to execute C# code wrote by a user.

To make some tests, I wrote this function :

public object executeDynamicCode(string code)
        {
            using (Microsoft.CSharp.CSharpCodeProvider foo = new Microsoft.CSharp.CSharpCodeProvider())
            {
                try
                {
                    var res = foo.CompileAssemblyFromSource(
                        new System.CodeDom.Compiler.CompilerParameters()
                        {
                            GenerateInMemory = true
                        },
                        "using System.Windows.Forms; public class FooClass { public void Execute() {MessageBox.Show();}}");
                    if (res.Errors.Count > 0)
                        MessageBox.Show(res.Errors[0].ErrorText);
                    var type = res.CompiledAssembly.GetType("FooClass");
                    var obj = Activator.CreateInstance(type);
                    var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
                    return output;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                    return null;
                }
            }
        }

But when I execute it, I got this error :

The type or namespace Windows does not exists in System namespace (an assembly reference are missing ?)

If someone got any idea ?

Thank you in advance !

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Thomas Rollet
  • 1,573
  • 4
  • 19
  • 33

1 Answers1

2

Add a namespace to it, matching your main project's namespace. I believe it's executing in a separate context since it doesn't have the same namespace, so it doesn't find the references included in the rest of the project.

Also, change your compiler options to

                    new System.CodeDom.Compiler.CompilerParameters()
                    {
                        GenerateInMemory = true,
                        CoreAssemblyFileName = "mscorlib.dll",
                        ReferencedAssemblies = { "System.dll", "System.Windows.dll", "System.Windows.Forms.dll","Microsoft.CSharp.dll" }
                    }

that works, I've tried it. You may not need all of those referenced assemblies, its the CoreAssemblyFileName that really mattered.

Eric Lizotte
  • 224
  • 1
  • 7