You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DiagnosticAnalyzer中通过相对路径读取文件内容?

解决DiagnosticAnalyzer中读取附加文件的问题

问题根源

你手动创建AnalyzerAdditionalFile实例的方式是错误的——SyntaxNodeAnalysisContext.Options.AdditionalFiles是由分析器框架根据项目配置自动填充的集合,无法通过手动实例化对象加入。另外,直接用File.ReadAllText读取相对路径,会因为分析器运行时的工作目录不确定导致找不到文件。

正确步骤

1. 修改.csproj配置

将原来的<Content>项替换为<AnalyzerAdditionalFiles>,这是分析器框架识别附加文件的专用项类型:

<ItemGroup>
  <AnalyzerAdditionalFiles Include="../../../docs/MyFile.txt">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    <!-- 若要打包NuGet,添加此项确保文件被包含 -->
    <Pack>True</Pack>
  </AnalyzerAdditionalFiles>
</ItemGroup>

2. 在分析器中读取附加文件

不需要自定义AdditionalText类,直接从分析上下文的Options.AdditionalFiles中获取目标文件:

方式一:在分析方法中实时读取

private void Analyze(
    SyntaxNodeAnalysisContext context,
    ClassDeclarationSyntax classDeclaration,
    ITypeSymbol type
)
{
    var cancellationToken = context.CancellationToken;
    // 根据文件名匹配目标附加文件
    var termsFile = context.Options.AdditionalFiles.FirstOrDefault(f => Path.GetFileName(f.Path) == "MyFile.txt");
    if (termsFile == null)
    {
        // 文件未找到,可返回或记录诊断信息
        return;
    }

    var documentationFileLines = new HashSet<string>();
    var fileText = termsFile.GetText(cancellationToken);
    foreach (var line in fileText.Lines)
    {
        documentationFileLines.Add(line.ToString());
    }

    // 后续业务逻辑...
}

方式二:在Initialize时预加载(优化性能)

如果文件内容无需每次分析都重新读取,可在初始化阶段一次性加载:

private HashSet<string> _preloadedDocumentationLines;

public override void Initialize(AnalysisContext context)
{
    base.Initialize(context);
    context.EnableConcurrentExecution();
    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

    // 预加载附加文件内容
    var cancellationToken = CancellationToken.None;
    var termsFile = context.Options.AdditionalFiles.FirstOrDefault(f => Path.GetFileName(f.Path) == "MyFile.txt");
    if (termsFile != null)
    {
        var fileText = termsFile.GetText(cancellationToken);
        _preloadedDocumentationLines = new HashSet<string>(fileText.Lines.Select(l => l.ToString()));
    }
    else
    {
        _preloadedDocumentationLines = new HashSet<string>();
    }

    context.HandleClassDeclaration(Analyze);
}

private void Analyze(
    SyntaxNodeAnalysisContext context,
    ClassDeclarationSyntax classDeclaration,
    ITypeSymbol type
)
{
    // 直接使用预加载的_preloadedDocumentationLines
    // 后续业务逻辑...
}

3. 调试注意事项

  • 若在Visual Studio中调试分析器,需确保测试项目的.csproj也配置了AnalyzerAdditionalFiles,或手动将文件复制到测试项目的输出目录。
  • 始终通过AdditionalText.GetText()获取文件内容,不要直接用File类读取路径,框架会自动处理文件的正确寻址。

内容的提问来源于stack exchange,提问作者Szyn33k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:50:55