Pregunta

Tengo dificultades para compilar dinámicamente una DLL para su uso con Silverlight 3.0. Mi objetivo es tomar algunas reglas proporcionadas por mis usuarios y recopilarlos en una DLL con fines de edición personalizada.

He creado un proyecto de biblioteca de clases de Silverlight en Visual Studio para obtener la línea de comandos para la compilación de una biblioteca de clases de Silverlight. En base a eso y los muchos ejemplos para la compilación de VB utilizando el VBCodeProvider, me ocurrió con el siguiente método para bocetos y maquetas de código en una cadena en un DLL:

Public Function Compile(ByVal code As String, ByVal assemblyName As String) As CompilerResults
    ' set the compiler parameters
    Dim parameters As CompilerParameters = New CompilerParameters()
    parameters.OutputAssembly = assemblyName
    parameters.GenerateInMemory = False
    parameters.GenerateExecutable = False
    parameters.IncludeDebugInformation = True

    ' constants for the silverlight assembly directories
    Dim sdkDir As String = "c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0\"
    Dim clientDir As String = "c:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Libraries\Client\"
    Dim riaDir As String = "C:\Program Files (x86)\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\"

    ' set referenced assemblies
    parameters.ReferencedAssemblies.Clear()
    parameters.ReferencedAssemblies.Add(sdkDir + "mscorlib.dll")
    parameters.ReferencedAssemblies.Add(sdkDir + "System.Core.dll")
    parameters.ReferencedAssemblies.Add(sdkDir + "system.dll")
    parameters.ReferencedAssemblies.Add(sdkDir + "System.Net.dll")
    parameters.ReferencedAssemblies.Add(sdkDir + "System.Windows.Browser.dll")
    parameters.ReferencedAssemblies.Add(sdkDir + "System.Windows.dll")
    parameters.ReferencedAssemblies.Add(sdkDir + "System.Xml.dll")

    ' build compiler options for sdk path to point to Silverlight.
    Dim options As String

    options = "/sdkpath:""" + sdkDir + "\"" "
    options = options + "/define:""SILVERLIGHT=1"""

    parameters.CompilerOptions = options

    ' compile
    Dim provider = New VBCodeProvider()
    Return provider.CompileAssemblyFromSource(parameters, code)
End Function

Mi unidad de clase de prueba que el código de la siguiente manera:

Public Sub CompileTest()

    ' Assemble
    Dim builder As StringBuilder = New StringBuilder()
    builder.AppendLine("Imports System")
    builder.AppendLine("Namespace Namespace1")
    builder.AppendLine("Public Class Class1")
    builder.AppendLine("Public Sub Test()")
    builder.AppendLine("Console.WriteLine(""Hello Compilation"")")
    builder.AppendLine("Console.ReadLine()")
    builder.AppendLine("End Sub")
    builder.AppendLine("End Class")
    builder.AppendLine("End Namespace")

    Dim assemblyName As String = ".\TestAssembly.dll"

    ' Act
    Dim compiler As SilverlightCompiler = New SilverlightCompiler()
    Dim cr As CompilerResults = compiler.Compile(builder.ToString(), assemblyName)

    ' Assert
    Assert.AreEqual(0, cr.Errors.Count)
End Sub

Esto no compila con el siguiente error:

VBC: Línea de Comando (0,0): BC2010 error: falló la compilación: 'miembro 'IsNumeric' no se puede encontrar en la clase 'Microsoft.VisualBasic.Information'. Esta condición es generalmente el resultado de una 'Microsoft.VisualBasic.dll' no coinciden. '

He buscado y, de hecho, la versión de Silverlight de la Microsoft.VisualBasic.Information clase no contiene miembro de IsNumeric. Por lo que parecen estar recogiendo las bibliotecas correctas utilizando la opción sdkpath. Pero no tengo idea de ¿Por qué Estoy tratando de llamar a ese método en el primer lugar.

¿Alguien puede arrojar luz sobre cómo compilar correctamente el código fuente de forma dinámica en una biblioteca de clases compatibles Silverlight? TIA.

¿Fue útil?

Solución

Se han encontrado la respuesta al obtener el proveedor de código para guardar los archivos temporales que estaba creando. Esto se hace añadiendo mi:

    parameters.TempFiles.KeepFiles = True

a las opciones del compilador.

Una vez hecho esto, la línea de comandos VBC y el código compilado que se quedó atrás en mi directorio temporal del usuario. En cuanto a ella, pude ver que estaba usando el compilador VBC en el directorio .Net 2.0, no el directorio 3.5.

Con el fin de conseguir que el compilador se utilice en el directorio 3.5, las líneas bajo el 'comentario de compilación se cambiaron a lo siguiente:

    ' compile
    Dim languageOptions As Dictionary(Of String, String) = New Dictionary(Of String, String)()
    languageOptions("CompilerVersion") = "v3.5"

    Dim provider = New VBCodeProvider(languageOptions)
    Return provider.CompileAssemblyFromSource(parameters, code)

Se utiliza una sobrecarga en el constructor que toma VBCodeProvider opciones de idioma. Un compañero de trabajo encontraron esta usando Reflector en el motor de plantillas T4; más tarde descubrí que documenta en un ejemplo aquí:

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

Una vez que esto se creó correctamente, el código compilado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top