miércoles, 27 de abril de 2011

Usando servicios de compilación de .NET

Hola en esta ocasión les mostraré lo fácil que es utilizar los servicios de compilación que nos ofrece .NET, para utilizar dichos servicios debemos utilizar la clase CSharpCodeProvider que se encuentran en el namespace Microsoft.CSharp en el caso que quisiéramos utilizar el compilador de CSharp, y Microsoft.VisualBasic para el caso de Visual Basic tenemos la clase VBCodeProvider. Bueno, también debemos utilizar algunas clases del namespace System.CodeDom.Compiler para poder adicionar parámetros como el tipo de ensamblado que se generará (exe o dll), a que ensamblados hará referencia (System.dll, etc.), recursos, etc. y también para la clase CompilerResults la cual nos indica el resultado de la compilación, si existieron errores durante la compilación, advertencias, etc.
El primer paso que debemos hacer es crear una instancia de la clase CSharpCodeProvider, la cual nos permitirá realizar la compilación.


 using Microsoft.CSharp;
 using System.CodeDom.Compiler;
 ..
 ..
 ..
 CSharpCodeProvider provider = new CSharpCodeProvider();


Si pueden explorar los métodos que tiene esta clase, podemos ver uno que será el que en palabras simples compilará cualquier código fuente CSharp válido que introduzcamos como parámetro, este método se llama CompileAssemblyFromSource, el cual recibe como parámetros el código fuente, pero también necesitamos CompilerParameters, los cuales especificaremos creando una instancia de esta clase que está en el namespace System.CodeDom.Compiler.


 provider.CompileAssemblyFromSource(parameters, sourceCode);



Una vez creado este objeto, tenemos que especificar si queremos generar un ejecutable o una dll, para eso establecemos en true la propiedad GenerateExecutable en caso que quisiéramos que se genere un ejecutable, caso contrario la ponemos en false. Además de esto debemos especificar los ensamblados a los que nuestro futuro ensamblado hará referencia, por ejemplo System.dll, estos los especificamos como cadenas de texto con el nombre de la dll, por si algunos nos saben, los ensamblados por defecto se encuentran registrados en la GAC, o los pueden encontrar en C:\%windir%\assembly\GAC y finalmente el último parámetro que estableceremos será el nombre del ensamblado el cual generaremos.


 CompilerParameters parameters = new CompilerParameters();
 
 parameters.GenerateExecutable = generateExecutable;
 parameters.ReferencedAssemblies.Add("System.dll");
 parameters.OutputAssembly = outputName;



Finalmente debemos compilar para eso llamamos al método se mencionó anteriormente, CompileAssemblyFromSource, pasándole como parámetros los parámetros de compilación mas el código fuente que queremos compilar, y este método nos devolverá los resultados en un objeto del tipo CompilerResults


 CompilerResults results = provider.CompileAssemblyFromSource(parameters, sourceCode);



Hasta esta parte, ya cumplimos con el objetivo que era utilizar los servicios de compilación que nos ofrece .NET para compilar código fuente en tiempo de ejecución. Pues dándole un poco mas de estilo a este fragmento de código podríamos mostrar los errores en caso que existieran, para eso utilizamos los resultados que obtuvimos de la compilación y verificamos si tiene errores, en caso que los tenga, los vamos añadiendo a un StringBuilder y listo.


StringBuilder errores = null;
if (results.Errors.Count > 0) {
 errores = new StringBuilder();
 foreach (CompilerError error in results.Errors) {
  errores.AppendLine(string.Format("Error en linea: {0}", error.Line));
  errores.AppendLine("\t" + error.ErrorText);
 }
}

Pues bien, como se pudo ver, utilizar los servicios de compilación que nos ofrece .NET es muy fácil, simplemente debemos usar dos namespaces y tres clases, obviamente podemos establecer mas parámetros, etc. El proyecto esta disponible para descargar. Bueno, espero les haya sido útil, hasta otra entrada.

1 comentario: