我使用此命令有一个自定义msbuild任务:

var workspace = Workspace.LoadStandAloneProject(csprojPath);

当我运行它时,它引发以下错误:

用户代码未处理System.InvalidCastException
Message =无法将透明代理转换为“Roslyn.Utilities.SerializableDataStorage”类型。
来源= Roslyn.Services
堆栈跟踪:
在Roslyn.Utilities.RemoteServices.CreateInstance [T]()
在Roslyn.Services.Host.TemporaryStorageServiceFactory.CreateService(IWorkspaceServiceProvider工作空间服务)
在Roslyn.Services.Host.WorkspaceServiceProviderFactory.Provider.c__DisplayClass7.b__4()
在Roslyn.Utilities.NonReentrantLazy`1.get_Value()
在Roslyn.Services.Host.WorkspaceServiceProviderFactory.Provider.GetService [TWorkspaceService]()
在Roslyn.Services.SolutionServices..ctor(IWorkspaceServiceProvider工作空间服务,ILanguageServiceProviderFactory语言服务工厂)
在Roslyn.Services.Solution..ctor(SolutionId id,String filePath,VersionStamp版本,VersionStamp最新项目版本,ILanguageServiceProviderFactory语言服务提供商工厂,IWorkspaceServiceProvider工作空间服务)
在Roslyn.Services.Host.SolutionFactoryServiceFactory.SolutionFactoryService.CreateSolution(SolutionId id)
在Roslyn.Services.Host.TrackingWorkspace.CreateNewSolution(ISolutionFactoryService solutionFactory,SolutionId id)
在Roslyn.Services.Host.TrackingWorkspace..ctor(IWorkspaceServiceProvider工作空间服务提供者, bool enableBackgroundCompilation, bool enableInProgressSolutions)
在Roslyn.Services.Host.HostWorkspace..ctor(IWorkspaceServiceProvider工作空间服务提供者, bool enableBackgroundCompilation, bool enableInProgressSolutions, bool enableFileTracking)
在Roslyn.Services.Host.LoadedWorkspace..ctor(ILanguageServiceProviderFactory languageServiceProviderFactory,IWorkspaceServiceProvider,workspaceServiceProvider,IProjectFileService projectFileFactsService,IDictionary`2 globalProperties,Boolean enableBackgroundCompilation,Boolean enableFileTracking)
在Roslyn.Services.Host.LoadedWorkspace..ctor(ExportProvider exportProvider, bool 解决方案LoadOnly, bool enableFileTracking)
在Roslyn.Services.Host.LoadedWorkspace..ctor( bool enableFileTracking)
在Roslyn.Services.Host.LoadedWorkspace.LoadStandAloneProject(String projectFileName,String configuration,String platform,String language,Boolean enableFileTracking)
在Roslyn.Services.Workspace.LoadStandAloneProject(String projectFileName,String configuration,String platform,String language,Boolean enableFileTracking)
...

在具有相同项目的控制台应用程序中运行时,相同的代码可以正常运行。

有任何想法吗?谷歌搜索没有帮助!

最佳答案

这是Roslyn的MsBuild任务示例。

为了重建Workspace.LoadProjectFromCommandLineArguments方法所需的命令行,我们必须将一些信息从msbuild文件传递到我们的任务中。

  • 引用的程序集:
    @(ReferencePath)项目组。
  • 要编译的cs文件:@(Compile)项目组。
  • 基本目录:$(MSBuildProjectDirectory)内置属性。

  • Roslyn只需这些即可解析您的源文件。 (请参阅本文末尾的注释。)

    因此,创建一个C#类库项目。
    这些是您需要的项目引用:
    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文件的末尾(紧接在结束的Project标记之前)添加以下行。但是仅当项目已经成功构建并且可以在输出文件夹中找到您的任务dll时才可以。
      <Target Name="AfterBuild" DependsOnTargets="RoslynTask"/>
      <UsingTask AssemblyFile="$(OutputPath)\RoslynMsBuildTask.dll" TaskName="RoslynMsBuildTask.RoslynTask" />
      <Target Name="RoslynTask">
        <RoslynTask ReferencePath="@(ReferencePath)" Compile="@(Compile)" BaseDirectory="$(MSBuildProjectDirectory)" />
      </Target>
    

    它将第一个cs文件的源转储到build输出。

    请注意,其他csc.exe开关(如ConditionalDirectives,输出类型等)也可能会有所不同,具体取决于您尝试执行的分析类型。您也可以使用此模式将它们传递给您的任务。有关MsBuild传递给csc.exe的属性的完整列表,请参见$(MSBuildToolsPath)\Microsoft.CSharp.targets文件,CoreCompile目标,Csc任务。

    关于c# - Roslyn:工作空间在控制台应用程序中加载,但不在msbuild任务中加载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13052115/

    10-13 07:02