2010-06-11 23 views
6

Potrzebuję utworzyć program, który tworzy inny program, ale nie jest kompilatorem.Program, który tworzy inny program

Na przykład

napisać program, który akceptuje wejście ciąg od użytkownika. Powiedzmy, że użytkownik wpisuje "Pluto". Ten program powinien następnie utworzyć osobny plik exe z napisem "Hello Pluto" po uruchomieniu.

Jak mogę to zrobić? Jeśli możesz dać przykład w C# i Windows Forms, to lepiej.

Dzięki.

+5

Czy możesz pokazać nam, co zrobiliście w tej pracy domowej? – 48klocs

+4

Wygląda bardzo podobnie do pytania "kod-to-mi" ... – Dykam

+7

Chciałem powiedzieć "to nie jest praca domowa", ale myślałem, że dasz mi korzyść z wątpliwości. Mam już 27 lat. To nie jest pytanie "skopiuj to dla mnie". Problem, który napotykam, jest naprawdę większy, ale ograniczam problem do prostego pytania powyżej. – zaidwaqi

Odpowiedz

14

Zasadniczo to kompilator - tylko dla szczególnie prostego języka.

Jeśli możesz wyrazić końcowy program w języku C#, najprostszym rozwiązaniem jest prawdopodobnie użycie CSharpCodeProvider. To właśnie robię dla Snippy, małego narzędzia, które pomaga w łatwym uruchamianiu fragmentów kodu dla C# in Depth. Kod źródłowy do Snippy to on the C# in Depth web site i może dać ci wyobrażenie o tym, co możesz zrobić - po prostu chcesz, aby zapisał plik wykonywalny do pliku, zamiast budować go w pamięci.

Alternatywnie, spójrz na MSDN docs, które mają przykład generujący plik wykonywalny.

+0

@Dvowie: Chcesz podać powód? –

+0

przegłosowano tylko ze względu na niego. jeśli spojrzysz na pierwszą stronę, ktoś po prostu ignoruje wszystko, co widzi. – Femaref

+2

coś pogrąża wszystko. Spójrz na listę pytań. Wiele dobrych pytań zostało odrzuconych. Proszę, przestań tego bota! –

11

Klasy szukasz znajdują się w przestrzeni nazw 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); 

(od microsoft support znaleźć za pomocą Google - przy mniej niż 20 sekund)

+3

dbać o podanie przyczyny spadku? – Femaref

+0

Ludzie, którzy nie przyjmują właściwych odpowiedzi, każą mi sprzeciwić się tym spadkobiercom. – Dykam

+0

Proszę nie używać protekcjonalnego tekstu w odpowiedzi dotyczącej google. Celem stackoverflow.com jest nie używać google i mieć tutaj odniesienie do kodu. W przeciwnym razie, dlaczego wszyscy nie używamy google? –

3

niepewnie, można również achive to bezpo¶rednio używał rzeczy w System.Reflection.Emit namespace i uważam, że możliwe jest zapewnienie implementacji metody za pomocą drzew wyrażeń LINQ. Który jest rodzajem schludny:

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

To może wyglądać nieco trudne na początku, ale to jest naprawdę fajne rzeczy, i niech kompilator generuje dysk rzeczy, wdrożenie metody. Ale naprawdę nie możesz stworzyć takich pól, to będzie wymagało trochę IL. To świetna zabawa, ale naprawdę żmudna praca.

ZASTRZEŻENIE:

nie próbowałem uruchomić powyższy kod. Ale wiem, że to coś takiego, minęło trochę czasu, odkąd zrobiłem coś takiego.

0

Najprostszym rozwiązaniem byłoby utwórz (z góry) naprawdę krótki, prosty program, który odczytuje z siebie zasoby i drukuje je. Wtedy twoja aplikacja potrzebuje tylko umieścić binarnie program na dysku i zadzwonić do funkcji UpdateResource, aby zmienić ciąg. .NET ma również obsługę zasobów, ale nie znam żadnej funkcji bezpośrednio odpowiadającej UpdateResource.

Powiązane problemy