1. #1
    AceInfinity's Avatar
    Join Date
    Feb 2012
    Location
    Canada
    Posts
    1,725

    [C#] CodeDOM Invocation Example



    Features:
    • Compile from textbox or file
      Change .NET Framework version
      Change reference assemblies


    Just a quick example i've put together as we haven't had much around here on CodeDOM at all... With this setup, and I haven't tested yet even though I should have, unsafe code context should work as well. :)

    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Reflection;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    
    namespace SourceRunner
    {
    	public partial class Form1 : Form
    	{
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		private void Form1_Load(object sender, EventArgs e)
    		{
    			comboBox1.SelectedIndex = 2;
    			textBox1.Text = "using System;\r\n" +
    							"using System.Collections.Generic;\r\n" +
    							"using System.ComponentModel;\r\n" +
    							"using System.Data;\r\n" +
    							"using System.Drawing;\r\n" +
    							"using System.Linq;\r\n" +
    							"using System.Text;\r\n" +
    							"using System.Windows.Forms;\r\n" +
    							"\r\n" +
    							"namespace CDNamespace\r\n" +
    							"{\r\n" +
    							"	public class CodeClass\r\n" +
    							"	{\r\n" +
    							"		public void Main()\r\n" +
    							"		{\r\n" +
    							"			//Entry Point\r\n" +
    							"		}\r\n" +
    							"	}\r\n" +
    							"}";
    			textBox1.SelectionStart = 0;
    		}
    
    		private void button1_Click(object sender, EventArgs e)
    		{
    			RunCode();
    		}
    
    		private void RunCode()
    		{
    			string ver = "v3.5";
    
    			switch (comboBox1.SelectedIndex)
    			{
    				case 0:
    					ver = "v2.0";
    					break;
    				case 1:
    					ver = "v3.0";
    					break;
    				case 2:
    					ver = "v3.5";
    					break;
    				case 3:
    					ver = "v4.0";
    					break;
    			}
    
    			string[] AssemInfo = File.ReadAllLines(Application.StartupPath + "\\ReferenceAssemblies.txt").Where(l => !l.StartsWith(@"//") && l.Contains(".dll")).ToArray();
    			Dictionary providerOptions = new Dictionary { { "CompilerVersion", ver } };
    			CSharpCodeProvider CSCodeProvider = new CSharpCodeProvider(providerOptions);
    
    			CompilerParameters CParams = new CompilerParameters();
    			CParams.GenerateInMemory = true;
    			CParams.CompilerOptions = "/optimize /unsafe";
    			CParams.ReferencedAssemblies.AddRange(AssemInfo);
    			//CParams.TempFiles = new TempFileCollection(Application.StartupPath + "\\TempFiles", false);
    
    			string CodePart = radioButton1.Checked ? File.ReadAllText(Application.StartupPath + "\\CompileCode.txt") : textBox1.Text;
    
    			CompilerResults objCompileResults = CSCodeProvider.CompileAssemblyFromSource(CParams, CodePart);
    			if (objCompileResults.Errors.HasErrors)
    			{
    				string[] Errors = objCompileResults.Errors.Cast().Select(e => string.Format("Error [Line: {0}]: {1}", e.Line.ToString(), e.ErrorText)).ToArray();
    				MessageBox.Show(string.Join("\n", Errors), string.Format("[{0}] Compiler Errors", Errors.Count()), MessageBoxButtons.OK, MessageBoxIcon.Error);
    				return;
    			}
    
    			object AssemblyInst = objCompileResults.CompiledAssembly.CreateInstance("CDNamespace.CodeClass");
    
    			try
    			{
    				if (AssemblyInst != null)
    					AssemblyInst.GetType().InvokeMember("Main", System.Reflection.BindingFlags.InvokeMethod, null, AssemblyInst, null);
    				else
    					MessageBox.Show("Cannot create instance of assembly...", "Null Object", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    			}
    			catch (Exception ex)
    			{
    				MessageBox.Show(string.Format("An error had occurred:\n\n{0}", ex.Message), "InvokeMember Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    			}
    		}
    	}
    }
    For the text files which have to be in the same working directory as the app at runtime:

    CompileCode.txt:
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace CDNamespace
    {
    	public class CodeClass
    	{
    		public void Main()
    		{
    			//Entry point
    		}
    	}
    }
    ReferenceAssemblies.txt: *I just added a whole bunch of crap here after I added in the main ones.
    Code:
    //This is a list of Referenced Assemblies
    
    mscorlib.dll
    System.dll
    System.Core.dll
    System.Data.dll
    System.Drawing.dll
    System.Windows.Forms.dll
    System.Configuration.dll
    System.Xml.dll
    System.Security.dll
    System.Web.RegularExpressions.dll
    System.Runtime.Serialization.Formatters.Soap.dll
    Download: To the one I compiled if you can't compile your own here.
    *See Attachment*
    Attached Files Attached Files
    tom982 says thanks for this.
    Automation Programmer
    Microsoft MVP [2012 - 2018]


    • Ad Bot

      advertising
      Beep.

        
       

  2. #2
    AceInfinity's Avatar
    Join Date
    Feb 2012
    Location
    Canada
    Posts
    1,725

    Re: [C#] CodeDOM Invocation Example

    EDIT: Yep, unsafe code works too



    Automation Programmer
    Microsoft MVP [2012 - 2018]

Log in

Log in