Created
July 17, 2013 19:11
-
-
Save AlexArchive/6023520 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.CSharp; | |
using Microsoft.VisualBasic; | |
using System; | |
using System.CodeDom; | |
using System.CodeDom.Compiler; | |
using System.IO; | |
using System.Reflection; | |
using System.Text; | |
namespace Code | |
{ | |
internal class Program | |
{ | |
private static void Main(string[] args) | |
{ | |
var codeNamespace = GenerateCodeNamespace(); | |
var codeCompileUnit = new CodeCompileUnit(); | |
codeCompileUnit.Namespaces.Add(codeNamespace); | |
string code = CompilationUtility.CompileCodeFromNamespace(codeNamespace, ProgrammingLanguage.CSharp); | |
Console.WriteLine(code); | |
CompilationUtility.CompileCodeCompileUnitToDisc( | |
codeCompileUnit, | |
"C:\\Users\\Alex\\Desktop\\Assembly.exe", | |
ProgrammingLanguage.CSharp); | |
Console.ReadKey(); | |
} | |
private static CodeNamespace GenerateCodeNamespace() | |
{ | |
var codeNamespace = MetaProgram.MakeCodeNamespace(); | |
var typeDeclaration = MetaProgram.MakeTypeDeclaration(); | |
var codeMethod = MetaProgram.MakeCodeMethod(); | |
var codeMethodComplete = MetaProgram.MakeCompleteCodeMethod(codeMethod); | |
typeDeclaration.Members.Add(codeMethodComplete); | |
codeNamespace.Types.Add(typeDeclaration); | |
return codeNamespace; | |
} | |
} | |
internal static class MetaProgram | |
{ | |
public static CodeNamespace MakeCodeNamespace() | |
{ | |
var codeNamespace = new CodeNamespace("Code"); | |
return codeNamespace; | |
} | |
public static CodeTypeDeclaration MakeTypeDeclaration() | |
{ | |
var myType = new CodeTypeDeclaration("Program") | |
{ | |
TypeAttributes = TypeAttributes.NotPublic | |
}; | |
return myType; | |
} | |
public static CodeMemberMethod MakeCodeMethod() | |
{ | |
var myMethod = new CodeEntryPointMethod | |
{ | |
Attributes = MemberAttributes.Private | MemberAttributes.Static, | |
Name = "Main", | |
}; | |
var myParam = new CodeParameterDeclarationExpression(typeof(string[]), "args"); | |
myMethod.Parameters.Add(myParam); | |
return myMethod; | |
} | |
public static CodeMemberMethod MakeCompleteCodeMethod(CodeMemberMethod codeMemberMethod) | |
{ | |
var refNumberOne = new CodeVariableReferenceExpression("numberOne"); | |
var refNumberTwo = new CodeVariableReferenceExpression("numberTwo"); | |
var refResult = new CodeVariableReferenceExpression("result"); | |
codeMemberMethod.Statements.Add( | |
new CodeVariableDeclarationStatement(typeof(int), "numberOne", new CodePrimitiveExpression(10))); | |
codeMemberMethod.Statements.Add( | |
new CodeVariableDeclarationStatement(typeof(int), "numberTwo", new CodePrimitiveExpression(10))); | |
codeMemberMethod.Statements.Add( | |
new CodeVariableDeclarationStatement(typeof(int), "result")); | |
codeMemberMethod.Statements.Add( | |
new CodeAssignStatement( | |
refResult, | |
new CodeBinaryOperatorExpression( | |
refNumberOne, | |
CodeBinaryOperatorType.Add, | |
refNumberTwo))); | |
var printExpression = new CodeMethodInvokeExpression( | |
new CodeTypeReferenceExpression(typeof(Console)), "WriteLine", refResult); | |
var readExpression = new CodeMethodInvokeExpression( | |
new CodeTypeReferenceExpression(typeof(Console)), "ReadKey"); | |
codeMemberMethod.Statements.Add(printExpression); | |
codeMemberMethod.Statements.Add(readExpression); | |
return codeMemberMethod; | |
} | |
} | |
internal static class CompilationUtility | |
{ | |
public static string CompileCodeFromNamespace(CodeNamespace codeNamespace, ProgrammingLanguage programmingLanguage) | |
{ | |
var codeDomProvider = ResolveCodeDomProvider(programmingLanguage); | |
var codeGeneratorOptions = new CodeGeneratorOptions() | |
{ | |
BracingStyle = "C", | |
IndentString = " ", | |
BlankLinesBetweenMembers = false | |
}; | |
var generatedCode = new StringBuilder(); | |
using (var textWriter = new StringWriter(generatedCode)) | |
codeDomProvider.GenerateCodeFromNamespace(codeNamespace, textWriter, codeGeneratorOptions); | |
return generatedCode.ToString(); | |
} | |
public static string CompileCodeCompileUnitToDisc(CodeCompileUnit codeCompileUnit, string path, | |
ProgrammingLanguage programmingLanguage) | |
{ | |
var codeDomProvider = ResolveCodeDomProvider(programmingLanguage); | |
var compilerParameters = new CompilerParameters | |
{ | |
GenerateExecutable = true, | |
OutputAssembly = path, | |
CompilerOptions = "/t:exe" | |
}; | |
var compilerResult = | |
codeDomProvider.CompileAssemblyFromDom(compilerParameters, codeCompileUnit); | |
if (compilerResult.Errors.Count > 0) | |
{ | |
foreach (var error in compilerResult.Errors) | |
{ | |
Console.WriteLine(error); | |
} | |
} | |
return compilerResult.PathToAssembly; | |
} | |
private static CodeDomProvider ResolveCodeDomProvider(ProgrammingLanguage programmingLanguage) | |
{ | |
switch (programmingLanguage) | |
{ | |
case ProgrammingLanguage.CSharp: | |
return new CSharpCodeProvider(); | |
case ProgrammingLanguage.VB: | |
return new VBCodeProvider(); | |
default: | |
throw new ArgumentException("No such langauge defined!", "programmingLanguage"); | |
} | |
} | |
} | |
public enum ProgrammingLanguage | |
{ | |
CSharp, | |
VB, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment