| ||||||||||||||||
Run - Time Compiling
by Retro
R u n - T i m e C o m p i l i n g b y R e t r o 1 7 t h A p r i l 2 0 0 6 h t t p : / / r e t r o . h o s t . s k w w w . r r l f . d e . v u ************************************************************************************* 1. I N T R O I'm going to show you today, on how you can compile source code at runtime in csharp. After finishing Letum I started to look into metamorphic code, after searching through google I came across a little something called csharp-scripting and what I will be showing you is exactly the same thing but within itself. 2. S Y N T A X We only need two namespaces to complete this task - Microsoft.CSharp - Contains classes that support compilation and code generation using the C# language. System.CodeDom.Compiler - Contains types for managing the generation and compilation of source code in supported programming languages. 3. P A R A M E T E R S To initialize the compiler we do the following // Get the provider for Microsoft.CSharp CodeDomProvider provider = new CSharpCodeProvider(); // CompilerParameters object represents the settings and options for an ICodeCompiler interface CompilerParameters cp = new CompilerParameters(); · cp.GenerateExecutable = true; If you set this to true, then when it compiles it will generate a executable file otherwise it will give you a dynamic link library. · cp.OutputAssembly = "test.exe"; Sets the name for the output. · cp.ReferencedAssemblies.Add( "System.dll" ); This adds an assembly reference. I've read that you need to add each one for every assembly you plan to use in your code, but while testing I found this is not the case. I managed to use other references in my code by just using the above assembly. · cp.GenerateInMemory = False; When set to false it will save the assembly has a physical file, ie an executable file, otherwise it will save it into memory. · cp.WarningLevel = 3; The warning level at which the compiler aborts compilation. (The default warning level in MSVS8 is 4) · cp.TreatWarningAsErrors = false; Sets whether the compiler should treat warning messages as errors. · cp.CompilerOptions = "/optimize"; Sets options for the compiler, the given example gives optimize output. · cp.MainClass = "Sample.Class1"; If needed you can specify the class that contains the main method of the executable. · cp.EmbeddedResources.Add("Default.resources"); Set the embedded resource file of the assembly. This is useful for culture-neutral resources, or default (fallback) resources. · cp.TempFile = new TempFileCollection(".", true); Set a temporary files collection. The TempFileCollection stores the temporary files generated during a build in the current directory, but does not delete them after compilation. 4. C O M P I L E R R E S U L T S Now we have provided the compiler with the options for compilation, we can now go ahead and compile our source code. This is easily accomplished but the following line of code. CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile); This will compile the code from a file, where the sourceFile will point to its full path, but you dont just have to compile by using this method though. The other ways in which it can be done are: · provider.CompileAssemblyFromDom Compiles an assembly based on the System.CodeDom trees contained in the specified array of CodeCompileUnit objects. · provider.CompileAssemblyFromSource Compiles an assembly from the specified array of strings containing source code, eg. a text box. After compilation has been done we can now check for errors if(cr.Errors.Count > 0) { // Display compilation errors. Console.WriteLine("Errors Found!") foreach(CompilerError ce in cr.Errors) { Console.WriteLine(" {0}", ce.ToString()); } } else { // Compilation OK Console.WriteLine("Compilation done with no errors") } Hopefully now you've understood on how to compile code at runtime, at which you can use however you see fit ************************************************************************************* retrouk[AT]gmail.com |