пятница, 31 августа 2007 г.

Компиляция кода из своей программы

В данный момент я пытаюсь написать более гибкий движок для скриптов. Основная идея - скрипты должны писаться не на каком-то там "псевдо-языке", а на обычном C#.
В принципе, первая попытка написать такой движок уже была. Каждый скрипт хранился в отдельном файле. При старте менеджера скриптов, он их компилировал и в дальнейшем они использовались в работе переводчика.
Ну а то, что в зависимости от количества этих самых скриптов скорость загрузки программы падала экспоненциально думаю и так понятно :)
Поэтому сейчас я делаю редактор скриптов, который бы в итоге генерировал сборку, понятную менеджеру модулей переводчика и, соответственно, которая и использовалась бы для анализа предложений в процессе перевода. Это позволит избежать компиляции при загрузке.
Ну а теперь перейдем к теме поста.
Итак, что нужно для того чтобы скомпилировать произвольный код написанный, например, на языке C# и получить в итоге .exe или .dll файл?
Оказывается все очень и очень просто:

public static void Compile(string code, out string errors)
{
CompilerParameters cp = new CompilerParameters(); 

//указываем список используемых сборок
cp.ReferencedAssemblies.Add("System.dll"); 

//генерируем .exe файл
cp.GenerateExecutable = true; 

//в файл с именем
cp.OutputAssembly = "c:\\tmp.exe"; 

//Здесь можно поставить true, если нет необходимости сохранять
//скомпилированный файл и вы умеете пользоваться сборками, 
//которые загружены в память :)
cp.GenerateInMemory = false;

CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerResults cr = provider.CompileAssemblyFromSource(cp, new string[] {code} );

if (cr.Errors.Count != 0) {
//если были ошибки при компиляции, выводим в errors их список StringBuilder sb = new StringBuilder(); foreach (CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } errors = sb.ToString(); } else errors = "Compiled!";
}
Ну а пока что можно полюбоваться на новый редактор :) Вот оно: