C# 使用Roslyn MSBuildWorkspace项目AddAnalyzerReference';t负载分析仪

C# 使用Roslyn MSBuildWorkspace项目AddAnalyzerReference';t负载分析仪,c#,compilation,roslyn,C#,Compilation,Roslyn,我正在做一个代码报告项目。 目前,我能够编译解决方案项目,获取与编译相关的诊断信息,等等。。 当我尝试加载自定义IDiagnosticanAnalyzer时,问题出现了,我尝试使用AnalyzerFileReference和AnalyzerImageReference,但没有任何结果,我总是访问项目。Analyzer为空 var inmutableArray = (new List<IDiagnosticAnalyzer> { new VariableEnde

我正在做一个代码报告项目。 目前,我能够编译解决方案项目,获取与编译相关的诊断信息,等等。。 当我尝试加载自定义IDiagnosticanAnalyzer时,问题出现了,我尝试使用AnalyzerFileReference和AnalyzerImageReference,但没有任何结果,我总是访问项目。Analyzer为空

var inmutableArray = (new List<IDiagnosticAnalyzer>
    {
        new VariableEndedWithIdNamedCorrectlyDiagnosticAnalyzer()
    }).ToImmutableArray();
var analyzerImageReference = new AnalyzerImageReference(inmutableArray);

foreach (Project project in solution.Projects)
{                  
    project.AddAnalyzerReference(analyzerImageReference );
    //No analizers loaded....
}
在这两种情况下都加载了分析器,但是当我得到编译和诊断时,我没有得到与此分析器相关的输出(我认为它们没有在get编译函数中被调用)


有什么建议吗?

正如我所评论的,大多数Roslyn对象是不可变的。这意味着像
AddAnalyzerReference()
这样的方法不会改变项目,而是返回一个新的项目

我没有分析仪来测试这一点,但我相信你可以使用以下方法。请注意,我使用的是
Solution.AddAnalyzerReference()
,而不是您使用的

var inmutableArray =(new List<IDiagnosticAnalyzer>
        {
            new VariableEndedWithIdNamedCorrectlyDiagnosticAnalyzer()
        }).ToImmutableArray();
var analyzerImageReference = new AnalyzerImageReference(inmutableArray);

Solution newSolution = solution;

//We iterate over the original solution
foreach (Project project in solution.Projects)
{                   
    //But we save our work in the newSolution
    newSolution = newSolution.AddAnalyzerReference(project.Id, analyzerImageReference);
}

//Now newSolution should contain all your changes.
//Maybe you want to save this reference?
solution = newSolution;
var inmutableArray=(新列表
{
新变量EndedWithidNamedCorrectlyDiagnosticanAnalyzer()
}).ToImmutableArray();
var analyzerImageReference=新analyzerImageReference(inmutableArray);
解决方案newSolution=解决方案;
//我们迭代原始解
foreach(解决方案中的项目。项目)
{                   
//但我们在新的解决方案中保存了我们的工作
newSolution=newSolution.AddAnalyzerReference(project.Id,analyzerImageReference);
}
//现在,newSolution应该包含所有更改。
//也许您想保存此引用?
解决方案=新的解决方案;

我找到了这样做的方法:

 public static Task<ImmutableArray<Diagnostic>> GetDiagnosticsAsync(this Compilation compilation, ImmutableArray<DiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken = default(CancellationToken))
    {
        options = options ?? new AnalyzerOptions(ImmutableArray<AdditionalStream>.Empty, ImmutableDictionary<string, string>.Empty);
        Compilation newCompilation = null;
        var analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, options, out newCompilation, cancellationToken);
        newCompilation.GetDiagnostics(cancellationToken);

        return analyzerDriver.GetDiagnosticsAsync();
    }
公共静态任务GetDiagnosticsAsync(此编译、ImmutableArray分析器、AnalyzerOptions选项、CancellationToken CancellationToken=default(CancellationToken)) {
选项=选项??新的分析选项(ImmutableArray)我有一个类似的问题,我已经回答了。
您必须使用编译。WithAnalyzer(analyzer)和getDiagnostics()项目(与Roslyn中的大多数项目一样)是不可变的。因此
AddAnalyzerReference()
不会改变项目,而是返回一个新项目。请参阅:我回答了我尝试过的同一个问题,它也可以工作,但是,当我得到编译时,我没有得到自定义分析器提供的结果。谢谢大家。我试着实现了这一点,并与“AnalyzerDriver由于其保护级别而无法访问”。有什么想法吗?
var compilation = newProject.GetCompilationAsync().Result;

var diagnostics =   compilation.GetDiagnostics();
var inmutableArray =(new List<IDiagnosticAnalyzer>
        {
            new VariableEndedWithIdNamedCorrectlyDiagnosticAnalyzer()
        }).ToImmutableArray();
var analyzerImageReference = new AnalyzerImageReference(inmutableArray);

Solution newSolution = solution;

//We iterate over the original solution
foreach (Project project in solution.Projects)
{                   
    //But we save our work in the newSolution
    newSolution = newSolution.AddAnalyzerReference(project.Id, analyzerImageReference);
}

//Now newSolution should contain all your changes.
//Maybe you want to save this reference?
solution = newSolution;
 public static Task<ImmutableArray<Diagnostic>> GetDiagnosticsAsync(this Compilation compilation, ImmutableArray<DiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken = default(CancellationToken))
    {
        options = options ?? new AnalyzerOptions(ImmutableArray<AdditionalStream>.Empty, ImmutableDictionary<string, string>.Empty);
        Compilation newCompilation = null;
        var analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, options, out newCompilation, cancellationToken);
        newCompilation.GetDiagnostics(cancellationToken);

        return analyzerDriver.GetDiagnosticsAsync();
    }