コンソールアプリケーションではなく、MSBuildのタスクでのワークスペースのロードコンソールアプリケーションで同じプロジェクトを実行すると、同じコードが正常に実行されます。ロスリン:私は、このコマンドを使用して、カスタムのMSBuildタスクを持っている
アイデア?グーグルが役に立たなかった!
コンソールアプリケーションではなく、MSBuildのタスクでのワークスペースのロードコンソールアプリケーションで同じプロジェクトを実行すると、同じコードが正常に実行されます。ロスリン:私は、このコマンドを使用して、カスタムのMSBuildタスクを持っている
アイデア?グーグルが役に立たなかった!
これはMSBuildの制限事項です。 Roslynはビルド中にMSBuildを再帰的に呼び出して、プロジェクトのプロパティ/ファイル/参照を判断することはできません。ビルド作業中にRoslyn IProject
を作成するには、代わりにLoadFromCommandLineArgs()
メソッドを使用してみてください。あなたは、CscTaskがコンパイラに渡されるのと同じ引数を取るようにあなたのタスクを構築する必要があります。
希望すると便利です。
ここでは、RoslynのサンプルMsBuildタスクを示します。
Workspace.LoadProjectFromCommandLineArgumentsメソッドで必要なコマンドラインを再構築するには、msbuildファイルの情報をタスクに渡す必要があります。
これは、Roslynがソースファイルを解析するのに必要なことです。 (この記事の末尾の注釈を参照してください)
C#クラスライブラリプロジェクトを作成します。 これらはあなたが必要とするプロジェクト参照している:あなたの最後に次の行を追加し、それが実際に機能することを実証するために
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();
}
}
}
:
Microsoft.Build.Framework
Microsoft.Build.Utilities.v4.0
Roslyn.Compilers
Roslyn.Services
カスタムのMSBuildタスクのためのコード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ファイルのソースをビルド出力にダンプします。
(などConditionalDirectives、出力タイプ、など)他のcsc.exeスイッチもかかわらあなたがやろうとしている分析の種類に応じてことがあります。このパターンを使用してタスクに渡すこともできます。 MsBuildがcsc.exeに渡すプロパティの完全なリストについては、$(MSBuildToolsPath)\ Microsoft.CSharp.targetsファイル、CoreCompileターゲット、Cscタスクを参照してください。
ここで同じ問題が発生します。誰でも? – kzu
@kzuは誰かが答えたように見えます。 –