콘솔 응용 프로그램에 있지만은 MSBuild 작업의 작업 부하 동일한 코드가 콘솔 응용 프로그램에서 실행될 때 동일한 프로젝트에서 제대로 실행됩니다.로슬린 :이 명령을 사용하여 사용자 지정은 MSBuild 작업을
아이디어가 있으십니까? 인터넷 검색이 도움이되지 않았습니다!
콘솔 응용 프로그램에 있지만은 MSBuild 작업의 작업 부하 동일한 코드가 콘솔 응용 프로그램에서 실행될 때 동일한 프로젝트에서 제대로 실행됩니다.로슬린 :이 명령을 사용하여 사용자 지정은 MSBuild 작업을
아이디어가 있으십니까? 인터넷 검색이 도움이되지 않았습니다!
이것은 MSBuild의 제한 사항입니다. Roslyn은 빌드 중에 프로젝트 속성/파일/참조를 결정하기 위해 MSBuild를 재귀 적으로 호출 할 수 없습니다. 빌드 작업 중에 Roslyn IProject
을 만들려면 대신 LoadFromCommandLineArgs()
메서드를 사용해보십시오. CscTask가 컴파일러에 전달되는 것과 동일한 인수를 사용하도록 작업을 구성해야합니다.
희망이 도움이됩니다.
다음은 Roslyn의 샘플 MsBuild 작업입니다.
Workspace.LoadProjectFromCommandLineArguments 메소드에 필요한 명령 줄을 재구성하려면 msbuild 파일의 일부 정보를 작업에 전달해야합니다.
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 작업을 참조하십시오.
여기에서 같은 문제가 발생합니다. 누군가? – kzu
@kzu 누군가가 대답 한 것처럼 보입니다. –