2009-10-14 67 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

一旦被正確設置,編譯的代碼。