我将用一个例子来解释这种情况。
假设我创建了一个Roslyn Analyzer,当类名是 测试类. 分析器的代码如下。
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(Method, SyntaxKind.ClassDeclaration);
}
private static void Method(SyntaxNodeAnalysisContext context)
{
var node = (ClassDeclarationSyntax)context.Node;
var name = node.TryGetInferredMemberName();
if(name == "TestClass")
{
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
}
}
所以我把Analyzero的nupkg安装到了某个 ConsoleApp 项目。控制台项目有以下代码 程序.cs 文件
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
class TestClass
{
static void test()
{
Console.WriteLine("TestClass");
}
}
}
现在,如果我在Visual Studio中构建ConsoleApp项目,我得到的错误是 "TestClass名称未被使用",这很好。VS 2017的开发者命令提示符 我在分析器中没有看到任何错误。我希望在VS的错误列表中显示的所有错误都能在Dev Cmd中显示出来,我的最终目标是创建一个独立的代码分析工具项目,然后使用MSBuildWorkspace编译ConsoleApp项目,并获得分析器的错误警告。
我的最终目标是创建一个独立的代码分析工具项目,然后使用MSBuildWorkspace编译ConsoleApp项目并获得分析器的错误警告。部分代码如下。
var filePath = @"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
var name = proj.Name;
var compilation = await proj.GetCompilationAsync();
errors.AddRange(compilation.GetDiagnostics().Where(n => n.Severity == DiagnosticSeverity.Error).ToList());
}
var count = errors.Count();
以上代码没有显示分析器的错误警告。
我怎样才能实现这个目标呢?Thanks in Advance.
如何在VS Dev Cmd & 使用MSBuildWorkspace在msbuild过程中显示Analyzer的错误警告。
其实这些警告来自于代码分析机制,而不是MSBuild警告(如 MSBxxx
). 而我认为 TestClass name not to be used
只是一个警告(黄色标记)而不是一个错误。
在VS IDE中其环境整合了 MSBuild工具(Developer Command Prompt for VS
)和 代码分析器. 正因为如此,你可以在VS IDE中得到警告。
然而,当你使用 开发者命令提示符它本质上是MSBuild的一个单独的编译工具,它没有一个集成的代码分析器,所以除了MSBuild的警告和错误之外,你不会有这种类型的警告(MSBxxx
). 这也是该工具的局限性。警告本身不会影响整个程序。
测试
你可以在一个空的控制台工程中输入这个来测试。int a=1;
(这是一个代码分析器警告),我确信该警告可以在VS IDE的输出窗口中显示,而不会在VS的开发者命令提示符中列出。
建议
作为一个建议,你可以尝试把这些警告当作错误来处理,并且 代码分析器 将这些警告传递给msbuild,并将它们指定为 错误 这样你就可以在 DEV.
将这些添加到您的 xxx.csproj
文件。
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
虽然 这种方法打破了构建过程,它是可靠和实用的。而且这种方法非常常用,一般用在项目的最后制作阶段,对大型项目排除所有错误和警告,防止后续可能出现的错误,做到万无一失。
然后,你就可以使用你的代码来构建项目。
要在VS Dev Cmd中的msbuild过程中显示分析器错误警告,你只需要通过rebuild开关,比如说msbuild Tempsolution.sln /t:rebuild
而对于MSBuidlWorkspace,这段代码对我来说是有效的。我们必须手动指定要使用的分析器,通过使用 compilation.WithAnalyzer(ImmutableArray<DiagnosticAnalyzer>);
.
MSBuildLocator.RegisterDefaults();
var filePath = @"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
var analyzer = proj.AnalyzerReferences.Where(alz => alz.Display.ToLower() == "Your analyzer name").FirstOrDefault();
var compilation = await proj.GetCompilationAsync();
var compWithAnalyzer = compilation.WithAnalyzers(analyzer.GetAnalyzersForAllLanguages());
var res = compWithAnalyzer.GetAllDiagnosticsAsync().Result;
errors.AddRange(res.Where(r => r.Severity == DiagnosticSeverity.Error).ToList());
}
var count = errors.Count();