Skip to content

Instantly share code, notes, and snippets.

@AlexArchive
Created July 17, 2013 19:11
Show Gist options
  • Save AlexArchive/6023520 to your computer and use it in GitHub Desktop.
Save AlexArchive/6023520 to your computer and use it in GitHub Desktop.
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