tags:

views:

254

answers:

5

Hi,

I need to create a program that creates another program but not a compiler though.

For example,

I write a program that accepts a string input from the user. Let's say user enter "Pluto". This program should then create a separate .exe that says "Hello Pluto" when executed.

How can I do this? If you could give example in C# and Windows Forms, it's better.

Thanks.

+14  A: 

Basically that is a compiler - just for a particularly simple language.

If you can express the final program in C#, the easiest solution is probably to use CSharpCodeProvider. That's what I do for Snippy, a little tool to help run code snippets easily for C# in Depth. The source code to Snippy is on the C# in Depth web site and can give you an idea of what you might do - basically you'd just want it to write the executable to a file instead of building it in memory.

Alternatively, look at the MSDN docs which have an example generating an executable.

Jon Skeet
@Downvoters: Care to give a reason?
Jon Skeet
upvoted just for the sake of it. if you look over the front page, somebody is just downvoting everything he sees.
Femaref
@Jon Skeet: something downvotes everything. Look at the question-list. Many good questions are downvoted. Please stop that bot!
Time Machine
+1 for snippy. That's a cute little project.
Scott P
+11  A: 

The classes you are looking for are in the Microsoft.CSharp namespace

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = icc.CompileAssemblyFromSource(parameters,SourceString);

(from microsoft support found by using google - taking less than 20 sec)

Femaref
care to give a reason for downvote?
Femaref
People downvoting proper answers makes me want to downvote those downvoters.
Dykam
Please don't use patronizing text in the answer regarding google. The whole point of stackoverflow.com is to not use google and have a coding reference here. Otherwise why don't we all just use google?
Gary Willoughby
Because certain things can't really be found by using google, because they are too specific to be found. In this case though, it was really easy to find. Now, if you have a question concerning something you've found (and appear to be spend thoughts on it) I don't have a problem with it.
Femaref
+3  A: 

Tentatively, you can also achive this throught he use of things in the System.Reflection.Emit namespace and I believe it's possible to provide the implementation of a method through the use of LINQ expression trees. Which is kind of neat:

var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("TestAssembly"), AssemblyBuilderAccess.RunAndSave);
var mod = assembly.DefineDynamicModule("TestModule");
var type = mod.DefineType("TestType");
var method = type.DefineMethod("Increment", MethodAttributes.Public, typeof(int), Type.EmptyTypes);
Expression<Func<int, int>> inc = (a) => a + 1; // this is cool
inc.CompileToMethod(method);

It might look a bit daunting at first, but it's really cool stuff, and you let the compiler generate the hard stuff, the method implementation. But you can't really create fields like this, that's gonna require some IL. Which is great fun but really tedious work.

DISCLAIMER:

I haven't tried to run the above code. But I know it goes something like that, it's been a while since I've done something like that.

John Leidegren
A: 

Use Reflection.Emit.

http://msdn.microsoft.com/en-us/library/8ffc3x75.aspx

http://www.codeproject.com/KB/cs/DynamicCodeGeneration2.aspx

How to build a HelloWorld.exe using Reflection.Emit (it's less than half-page of code): http://blogs.msdn.com/b/joelpob/archive/2004/01/21/61411.aspx

code4life
A: 

The easiest thing to do would be to create (in advance) a really short simple program that reads a resource from itself and prints it. Then your application needs only to place that program binary on disk somewhere and call the UpdateResource function to change the string. .NET also has resource support, but I don't know of any function that directly corresponds to UpdateResource.

Ben Voigt