2009-10-14 66 views
1

我很难动态编译用于Silverlight 3.0的DLL。我的目标是采用我的用户提供的一些规则,并将它们编译到DLL中以进行自定义编辑。需要帮助使用VBCodeProvider编译DLL for Silverlight 3.0

我在Visual Studio中创建了一个Silverlight类库项目,以获取用于编译Silverlight类库的命令行。基于这一点,编译使用VBCodeProvider VB的例子很多,我想出了下面的方法在一个字符串作曲代码到一个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”不匹配造成的。

我看了,实际上,Microsoft.VisualBasic.Information类的Silverlight版本不包含成员IsNumeric。所以我似乎使用sdkpath选项来选择正确的库。但我不知道为什么我试图首先调用该方法。

任何人都可以阐明如何成功地将源代码动态编译到兼容Silverlight的类库中吗? TIA。

回答

1

通过让代码提供者保存它创建的临时文件来找到答案。这是我加入:

parameters.TempFiles.KeepFiles = True 

给编译器选项。

完成此操作后,vbc命令行及其编译的代码将留在我的用户临时目录中。看着它,我可以看到我在.Net 2.0目录中使用了vbc编译器,而不是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构造函数语言选项超载。一位同事在T4模板引擎上使用Reflector发现了这一点;后来我发现它在这里的例子证明:

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

一旦被正确设置,编译的代码。