Нужна помощь в компиляции DLL для Silverlight 3.0 с VBCodeProvider

У меня возникают проблемы с динамической компиляцией DLL для использования с Silverlight 3.0. Моя цель - взять некоторые правила, предоставленные моими пользователями, и скомпилировать их в DLL для пользовательских целей редактирования.

Я создал проект библиотеки классов Silverlight в Visual Studio, чтобы получить командную строку для компиляции библиотеки классов Silverlight. Основываясь на этом и многочисленных примерах для компиляции VB с использованием VBCodeProvider, я придумал следующий метод для компоновки кода в строке в 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

Мой класс модульного теста, который кодируется следующим образом:

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

Это не компилируется со следующей ошибкой:

vbc: командная строка (0,0): ошибка BC2010: ошибка компиляции: "Элемент 'IsNumeric” не найден в классе "Microsoft.VisualBasic.Information". Это условие обычно является результатом несовпадающего "Microsoft.VisualBasic.dll".

Я посмотрел и, по сути, версию Silverlight класса Microsoft.VisualBasic.Information не содержит члена IsNumeric. Поэтому я, похоже, подбираю правильные библиотеки с помощью опции sdkpath. Но я понятия не имею, почему я пытаюсь вызвать этот метод в первую очередь.

Может кто-нибудь пролить свет на то, как успешно скомпилировать исходный код динамически в совместимую с Silverlight библиотеку классов? ТИА.

1 ответ

Решение

Нашел ответ, заставив провайдера кода сохранить временные файлы, которые он создавал. Это сделано мое добавление:

    parameters.TempFiles.KeepFiles = True

к параметрам компилятора.

Когда это было сделано, командная строка vbc и скомпилированный код остались в моем временном каталоге пользователя. Глядя на это, я мог видеть, что я использовал компилятор vbc в каталоге.Net 2.0, а не в каталоге 3.5.

Чтобы заставить его использовать компилятор в каталоге 3.5, строки под комментарием к компиляции были изменены на следующее:

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

Он использует перегрузку в конструкторе VBCodeProvider, который принимает языковые параметры. Сотрудник нашел это с помощью Reflector на шаблонном движке T4; позже я нашел это документально в примере здесь:

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

Как только это было установлено правильно, код скомпилирован.

Другие вопросы по тегам