2012-10-24 1 views
6

콘솔 응용 프로그램에 있지만은 MSBuild 작업의 작업 부하 동일한 코드가 콘솔 응용 프로그램에서 실행될 때 동일한 프로젝트에서 제대로 실행됩니다.로슬린 :이 명령을 사용하여 사용자 지정은 MSBuild 작업을

아이디어가 있으십니까? 인터넷 검색이 도움이되지 않았습니다!

+0

여기에서 같은 문제가 발생합니다. 누군가? – kzu

+0

@kzu 누군가가 대답 한 것처럼 보입니다. –

답변

-1

이것은 MSBuild의 제한 사항입니다. Roslyn은 빌드 중에 프로젝트 속성/파일/참조를 결정하기 위해 MSBuild를 재귀 적으로 호출 할 수 없습니다. 빌드 작업 중에 Roslyn IProject을 만들려면 대신 LoadFromCommandLineArgs() 메서드를 사용해보십시오. CscTask가 컴파일러에 전달되는 것과 동일한 인수를 사용하도록 작업을 구성해야합니다.

희망이 도움이됩니다.

3

다음은 Roslyn의 샘플 MsBuild 작업입니다.

Workspace.LoadProjectFromCommandLineArguments 메소드에 필요한 명령 줄을 재구성하려면 msbuild 파일의 일부 정보를 작업에 전달해야합니다.

  • 참조 된 어셈블리는 @ (ReferencePath) 항목 그룹입니다.
  • 컴파일 할 CS 파일 : @ (컴파일) 항목 그룹.
  • 기본 디렉터리 : $ (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 파일 (프로젝트 태그 닫기 직전). 그러나 프로젝트가 이미 성공적으로 빌드 된 경우에만 출력 폴더에서 작업 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 파일의 원본을 빌드 출력으로 덤프합니다. 기타에는 Csc.exe 스위치 (ConditionalDirectives, 출력 타입 등 같은)도없이 당신이하려고하는 분석의 종류에 따라 수


참고. 이 패턴을 사용하여 작업에 전달할 수도 있습니다. MsBuild가 csc.exe에 전달하는 전체 속성 목록은 $ (MSBuildToolsPath) \ Microsoft.CSharp.targets 파일, CoreCompile 대상, Csc 작업을 참조하십시오.

+0

ConditionalDirectives, 출력 유형 등과 같은 다른 스위치는 수행하려고하는 분석 유형에 따라 달라질 수 있지만 이는 좋은 출발점입니다. –

+0

@ 케빈 : 정보 주셔서 감사합니다, 나는 그것을 내 대답에 추가했습니다. – Vizu

+0

나를 위해, 이것은 동일한 예외에서 산출한다. ('Roslyn.Utilities.SerializableDataStorage'를 입력 할 수있는 투명한 프록시를 캐스팅 할 수 없음) – Imi

관련 문제