2010-06-11 7 views
6

J'ai besoin de créer un programme qui crée un autre programme mais pas un compilateur.Un programme qui crée un autre programme

Par exemple,

J'écris un programme qui accepte une entrée de chaîne de l'utilisateur. Supposons que l'utilisateur entre "Pluton". Ce programme devrait ensuite créer un fichier .exe distinct qui dit "Hello Pluto" lorsqu'il est exécuté.

Comment est-ce que je peux faire ceci? Si vous pouviez donner un exemple en C# et Windows Forms, c'est mieux.

Merci.

+5

Pourriez-vous nous montrer ce que vous avez fait jusqu'à maintenant? – 48klocs

+4

Cela ressemble beaucoup à une question de code-pour-moi ... – Dykam

+7

Je voulais mettre "ce n'est pas des devoirs", mais je pensais que vous me donneriez le bénéfice du doute. J'ai déjà 27 ans. Ce n'est pas "code pour moi" question. Le problème auquel je fais face est vraiment beaucoup plus grand, mais je réduis le problème à la question simple ci-dessus. – zaidwaqi

Répondre

14

Fondamentalement que est un compilateur - juste pour une langue particulièrement simple.

Si vous pouvez exprimer le programme final en C#, la solution la plus simple est probablement d'utiliser CSharpCodeProvider. C'est ce que je fais pour Snippy, un petit outil pour aider à exécuter des extraits de code facilement pour C# en profondeur. Le code source de Snippy est on the C# in Depth web site et peut vous donner une idée de ce que vous pourriez faire - en gros, vous voudriez simplement écrire l'exécutable dans un fichier au lieu de le créer en mémoire.

Vous pouvez également consulter le MSDN docs qui contient un exemple de fichier exécutable.

+0

@Downvoters: Vous voulez donner une raison? –

+0

upvoted juste pour le plaisir. Si vous regardez sur la première page, quelqu'un est en train de downvoter tout ce qu'il voit. – Femaref

+2

quelque chose downvotes tout. Regardez la liste des questions. Beaucoup de bonnes questions sont downvoted. S'il vous plaît arrêter ce bot! –

11

Les classes que vous recherchez sont dans l'espace de noms Microsoft.CSharp

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); 

(de microsoft support trouvé en utilisant google - prendre moins de 20 sec)

+3

soin de donner une raison pour downvote? – Femaref

+0

Les gens downvoting réponses correctes me donne envie de downvote ces downvoters. – Dykam

+0

S'il vous plaît ne pas utiliser de texte condescendant dans la réponse concernant google. Le but de stackoverflow.com est de ne pas utiliser Google et d'avoir une référence de codage ici. Sinon, pourquoi n'utilisons-nous pas tous Google? –

3

Provisoirement, vous pouvez aussi ACHIVE ce throught il utilise des choses dans l'espace de noms System.Reflection.Emit et je crois qu'il est possible de fournir l'implémentation d'une méthode grâce à l'utilisation d'arborescences d'expression LINQ. Ce qui est plutôt drôle:

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); 

Il peut sembler un peu intimidant au début, mais il y a des choses vraiment cool, et vous laisser le compilateur générer les choses difficiles, la mise en œuvre de la méthode. Mais vous ne pouvez pas vraiment créer des champs comme celui-ci, ça va nécessiter de l'IL. Ce qui est très amusant mais très fastidieux.

AVERTISSEMENT:

Je n'ai pas essayé d'exécuter le code ci-dessus. Mais je sais que ça se passe quelque chose comme ça, ça fait longtemps que j'ai fait quelque chose comme ça.

0

La meilleure chose à faire serait de créer (à l'avance) un programme simple très court qui lit une ressource de lui-même et l'imprime. Ensuite, votre application doit seulement placer ce programme binaire sur le disque quelque part et appeler la fonction UpdateResource pour changer la chaîne. .NET a également un support de ressources, mais je ne connais aucune fonction qui correspond directement à UpdateResource.

Questions connexes