2012-10-24 22 views
6

मैं इस आदेश के साथ एक कस्टम MSBuild कार्य है:रोसलिन: सांत्वना आवेदन में लेकिन MSBuild कार्य में नहीं कार्यक्षेत्र लोड

 
    System.InvalidCastException was unhandled by user code 
    Message=Unable to cast transparent proxy to type 'Roslyn.Utilities.SerializableDataStorage'. 
    Source=Roslyn.Services 
    StackTrace: 
     at Roslyn.Utilities.RemoteServices.CreateInstance[T]() 
     at Roslyn.Services.Host.TemporaryStorageServiceFactory.CreateService(IWorkspaceServiceProvider workspaceServices) 
     at Roslyn.Services.Host.WorkspaceServiceProviderFactory.Provider.c__DisplayClass7.b__4() 
     at Roslyn.Utilities.NonReentrantLazy`1.get_Value() 
     at Roslyn.Services.Host.WorkspaceServiceProviderFactory.Provider.GetService[TWorkspaceService]() 
     at Roslyn.Services.SolutionServices..ctor(IWorkspaceServiceProvider workspaceServices, ILanguageServiceProviderFactory languageServicesFactory) 
     at Roslyn.Services.Solution..ctor(SolutionId id, String filePath, VersionStamp version, VersionStamp latestProjectVersion, ILanguageServiceProviderFactory languageServiceProviderFactory, IWorkspaceServiceProvider workspaceServices) 
     at Roslyn.Services.Host.SolutionFactoryServiceFactory.SolutionFactoryService.CreateSolution(SolutionId id) 
     at Roslyn.Services.Host.TrackingWorkspace.CreateNewSolution(ISolutionFactoryService solutionFactory, SolutionId id) 
     at Roslyn.Services.Host.TrackingWorkspace..ctor(IWorkspaceServiceProvider workspaceServiceProvider, Boolean enableBackgroundCompilation, Boolean enableInProgressSolutions) 
     at Roslyn.Services.Host.HostWorkspace..ctor(IWorkspaceServiceProvider workspaceServiceProvider, Boolean enableBackgroundCompilation, Boolean enableInProgressSolutions, Boolean enableFileTracking) 
     at Roslyn.Services.Host.LoadedWorkspace..ctor(ILanguageServiceProviderFactory languageServiceProviderFactory, IWorkspaceServiceProvider workspaceServiceProvider, IProjectFileService projectFileFactsService, IDictionary`2 globalProperties, Boolean enableBackgroundCompilation, Boolean enableFileTracking) 
     at Roslyn.Services.Host.LoadedWorkspace..ctor(ExportProvider exportProvider, Boolean solutionLoadOnly, Boolean enableFileTracking) 
     at Roslyn.Services.Host.LoadedWorkspace..ctor(Boolean enableFileTracking) 
     at Roslyn.Services.Host.LoadedWorkspace.LoadStandAloneProject(String projectFileName, String configuration, String platform, String language, Boolean enableFileTracking) 
     at Roslyn.Services.Workspace.LoadStandAloneProject(String projectFileName, String configuration, String platform, String language, Boolean enableFileTracking) 
     ... 

:

var workspace = Workspace.LoadStandAloneProject(csprojPath); 

जब मैंने इसे चलाने के लिए, यह निम्न त्रुटि फेंकता एक ही कोड, एक ही प्रोजेक्ट के साथ, एक कंसोल एप्लिकेशन में चलाए जाने पर, ठीक चलता है।

कोई विचार? गुगलिंग सहायक नहीं रही है!

+0

वही समस्या यहां। किसी को? – kzu

+0

@kzu ऐसा लगता है कि किसी ने उत्तर दिया है। –

उत्तर

-1

यह एमएसबिल्ड की एक सीमा है। प्रोजेक्ट गुण/फाइल/संदर्भों को निर्धारित करने के लिए Roslyn एक बिल्ड के दौरान एमएसबिल्ड को पुनरावर्ती रूप से नहीं बुला सकता है। एक बिल्ड कार्य के दौरान Roslyn IProject बनाने के लिए, इसके बजाय LoadFromCommandLineArgs() विधि का उपयोग करने का प्रयास करें। CscTask को कंपाइलर को पास करने के समाप्त होने के बाद आपको एक ही तर्क लेने के लिए अपना कार्य बनाना होगा।

आशा है कि इससे मदद मिलती है!

3

रोज़लिन के साथ एक नमूना एमएसबिल्ड कार्य है।

वर्कस्पेस .LoadProjectFromCommandLineArguments विधि द्वारा आवश्यक कमांड लाइन को पुनर्निर्माण करने के लिए, हमें msbuild फ़ाइल से कुछ कार्य हमारे कार्य में पास करना होगा।

  • संदर्भित असेंबली: @ (संदर्भपैथ) आइटम समूह।
  • सीएस फाइलों को संकलित करने के लिए: @ (संकलित) आइटम समूह।
  • आधार निर्देशिका: $ (MSBuildProjectDirectory) अंतर्निहित संपत्ति।

यह सब कुछ है कि रोज़लिन को आपकी स्रोत फ़ाइलों को पार्स करने की आवश्यकता है। (इस पोस्ट के अंत में नोट देखें।)

तो सी # क्लास लाइब्रेरी प्रोजेक्ट बनाएं। ये परियोजना संदर्भ है कि आप की आवश्यकता होगी:

Microsoft.Build.Framework 
Microsoft.Build.Utilities.v4.0 
Roslyn.Compilers 
Roslyn.Services 

कस्टम MSBuild कार्य के लिए कोड:

using Microsoft.Build.Framework; 
using Microsoft.Build.Utilities; 
using Roslyn.Services; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace RoslynMsBuildTask 
{ 
    public class RoslynTask : Task 
    { 
     [Required] 
     public ITaskItem[] ReferencePath { get; set; } 

     [Required] 
     public ITaskItem[] Compile { get; set; } 

     [Required] 
     public ITaskItem BaseDirectory { get; set; } 

     public override bool Execute() 
     { 
      Log.LogMessage(MessageImportance.High, "RoslynTask.Execute called...\n"); 

      // Format the command line with the minimal info needed for Roslyn to create a workspace. 
      var commandLineForProject = string.Format("/reference:{0} {1}", 
       ReferencePath.Select(i => i.ItemSpec).ToSingleString(",", "\"", "\""), 
       Compile.Select(i => i.ItemSpec).ToSingleString(" ", "\"", "\"")); 

      // Create the Roslyn workspace. 
      var workspace = Workspace.LoadProjectFromCommandLineArguments("MyProject", "C#", commandLineForProject, BaseDirectory.ItemSpec); 

      // Make sure that Roslyn actually parsed the project: dump the source from a syntax tree to the build log. 
      Log.LogMessage(MessageImportance.High, workspace.CurrentSolution.Projects.First() 
       .Documents.First(i => i.FilePath.EndsWith(".cs")).GetSyntaxRoot().GetText().ToString()); 

      return true; 
     } 
    } 

    public static class IEnumerableExtension 
    { 
     public static string ToSingleString<T>(this IEnumerable<T> collection, string separator, string leftWrapper, string rightWrapper) 
     { 
      var stringBuilder = new StringBuilder(); 

      foreach (var item in collection) 
      { 
       if (stringBuilder.Length > 0) 
       { 
        if (!string.IsNullOrEmpty(separator)) 
         stringBuilder.Append(separator); 
       } 

       if (!string.IsNullOrEmpty(leftWrapper)) 
        stringBuilder.Append(leftWrapper); 

       stringBuilder.Append(item.ToString()); 

       if (!string.IsNullOrEmpty(rightWrapper)) 
        stringBuilder.Append(rightWrapper); 
      } 

      return stringBuilder.ToString(); 
     } 
    } 
} 

प्रदर्शित करने के लिए कि यह वास्तव में काम करता है, के अंत में निम्न पंक्तियां जोड़ें अपने csproj फ़ाइल (समापन परियोजना टैग से ठीक पहले)। लेकिन केवल अगर परियोजना पहले से ही सफलतापूर्वक बनाई गई थी और यह आउटपुट फ़ोल्डर में आपका कार्य डीएल पा सकता है।

<Target Name="AfterBuild" DependsOnTargets="RoslynTask"/> 
    <UsingTask AssemblyFile="$(OutputPath)\RoslynMsBuildTask.dll" TaskName="RoslynMsBuildTask.RoslynTask" /> 
    <Target Name="RoslynTask"> 
    <RoslynTask ReferencePath="@(ReferencePath)" Compile="@(Compile)" BaseDirectory="$(MSBuildProjectDirectory)" /> 
    </Target> 

यह आपके पहले सीएस फ़ाइल के स्रोत को निर्माण आउटपुट में डंप करेगा।


ध्यान दें कि अन्य Csc.exe स्विच (ConditionalDirectives, उत्पादन प्रकार, आदि जैसे) भी इस मामले विश्लेषण तुम क्या करने की कोशिश कर रहे के प्रकार पर निर्भर हो सकता है। आप इस पैटर्न का उपयोग करके उन्हें अपने कार्य में भी पास कर सकते हैं। MsBuild csc.exe को पास करने वाली गुणों की पूरी सूची के लिए $ (MSBuildToolsPath) \ Microsoft.CSharp.targets फ़ाइल, CoreCompile लक्ष्य, सीएससी कार्य देखें।

+0

ध्यान दें कि अन्य स्विच जैसे कि सशर्त डायरेक्टिव्स, आउटपुट टाइप इत्यादि, मई के विश्लेषण के प्रकार के आधार पर मामला हो सकता है, लेकिन यह एक महान प्रारंभिक बिंदु है! –

+0

@ केविन: जानकारी के लिए धन्यवाद, मैंने इसे अपने उत्तर में जोड़ा है। – Vizu

+0

मेरे लिए, यह एक ही अपवाद में पैदा होता है। ('Roslyn.Utilities.SerializableDataStorage' टाइप करने के लिए पारदर्शी प्रॉक्सी डालने में असमर्थ) – Imi