Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解析;静态分析结果交换格式(SARIF)";在MSBuild中_C#_Msbuild_Static Code Analysis - Fatal编程技术网

C# 解析;静态分析结果交换格式(SARIF)";在MSBuild中

C# 解析;静态分析结果交换格式(SARIF)";在MSBuild中,c#,msbuild,static-code-analysis,C#,Msbuild,Static Code Analysis,在使用MSBuild对项目运行各种分析器时,所有失败都将以“静态分析结果交换格式(SARIF)”格式输出(参见示例)。例如,构建可能会产生以下结果 { "version": "0.1", "toolInfo": { "toolName": "Microsoft (R) Visual C# Compiler", "productVersion": "1.1.0", "fileVersion": "1.1.0" }, "issues": [ {

在使用MSBuild对项目运行各种分析器时,所有失败都将以“静态分析结果交换格式(SARIF)”格式输出(参见示例)。例如,构建可能会产生以下结果

{
  "version": "0.1",
  "toolInfo": {
    "toolName": "Microsoft (R) Visual C# Compiler",
    "productVersion": "1.1.0",
    "fileVersion": "1.1.0"
  },
  "issues": [
    {
      "ruleId": "SA1401",
      "locations": [
        {
          "analysisTarget": [
            {
              "uri": "C:\\SomeFile.cs",
              "region": {
                "startLine": 708,
                "startColumn": 30,
                "endLine": 708,
                "endColumn": 36
              }
            }
          ]
        }
      ],
      "shortMessage": "Field must be private",
      "fullMessage": "A field within a C# class has an access modifier other than private.",
      "properties": {
        "severity": "Warning",
        "warningLevel": "1",
        "defaultSeverity": "Warning",
        "title": "Fields must be private",
        "category": "StyleCop.CSharp.MaintainabilityRules",
        "helpLink": "https:\/\/github.com\/DotNetAnalyzers\/StyleCopAnalyzers\/blob\/master\/documentation\/SA1401.md",
        "isEnabledByDefault": "True",
        "isSuppressedInSource": "True"
      }
    }
  ]
}
现在,我希望能够以最简单的方式解析上面的数据(如果遇到任何非抑制问题,则中断构建)。怎么做呢


另外,我还希望避免实现自己的MSBuild任务和安装特定软件(例如PowerShell 3.0-从Json转换而来)。

因为显然没有内置的方法来实现这一点,我最终使用了内联MSBuild任务(),定义为

<UsingTask TaskName="ParseUnsupressedAnalysisIssues" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
    <ParameterGroup>
        <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
        <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
    </ParameterGroup>
    <Task>
        <Reference Include="System.Runtime.Serialization" />
        <Reference Include="System.Xml" />
        <Reference Include="System.Xml.Linq" />
        <Using Namespace="System"/>
        <Using Namespace="System.Collections.Generic"/>
        <Using Namespace="System.IO"/>
        <Using Namespace="System.Linq"/>
        <Using Namespace="System.Runtime.Serialization.Json"/>
        <Using Namespace="System.Xml"/>
        <Using Namespace="System.Xml.Linq"/>
        <Code Type="Fragment" Language="cs">
            <![CDATA[
            List<TaskItem> taskItems = new List<TaskItem>();
            foreach(ITaskItem item in Files)
            {
                try
                {
                    string path = item.GetMetadata("FullPath");
                    using (FileStream fs = new FileStream(path, FileMode.Open))
                    using (XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(fs, XmlDictionaryReaderQuotas.Max))
                    {
                        XElement doc = XElement.Load(reader);
                        XElement issuesRoot = doc.Elements("issues").SingleOrDefault();
                        List<XElement> unsupressedIssues = issuesRoot.Elements("item").Where(e => !"True".Equals((string)e.Element("properties").Element("isSuppressedInSource"), StringComparison.Ordinal)).ToList();
                        string unsupressedIssuesString = string.Join(Environment.NewLine, unsupressedIssues);
                        if(!string.IsNullOrEmpty(unsupressedIssuesString))
                        {
                            taskItems.Add(new TaskItem(item.ItemSpec));
                            Console.WriteLine(unsupressedIssuesString);
                        }
                    }
                }
                catch(Exception e)
                {
                    taskItems.Add(new TaskItem(item.ItemSpec));
                    Console.WriteLine(e.ToString());
                }
            }

            Result = taskItems.ToArray();
            ]]>
        </Code>
    </Task>
</UsingTask>


taskItems=新列表();
foreach(文件中的ITaskItem项)
{
尝试
{
字符串路径=item.GetMetadata(“完整路径”);
使用(FileStream fs=newfilestream(路径,FileMode.Open))
使用(XmlDictionaryReader=JsonReaderWriterFactory.CreateJsonReader(fs,XmlDictionaryReaderQuotas.Max))
{
XElement doc=XElement.Load(读卡器);
XElement issueroot=doc.Elements(“问题”).SingleOrDefault();
List unpressedissues=issueroot.Elements(“item”)。其中(e=>!“True”。等于((string)e.Element(“properties”)。Element(“isSuppressedInSource”),StringComparison.Ordinal)。ToList();
string unpressedissuessstring=string.Join(Environment.NewLine,unpressedissues);
如果(!string.IsNullOrEmpty(unpresseDissuessString))
{
添加(新任务项(item.ItemSpec));
Console.WriteLine(未按下的字符串);
}
}
}
捕获(例外e)
{
添加(新任务项(item.ItemSpec));
Console.WriteLine(如ToString());
}
}
结果=taskItems.ToArray();
]]>

然后可以作为

<ParseUnsupressedAnalysisIssues Files="@(AnalyzerFiles)">
    <Output ItemName="FailedAnalyzerFiles" TaskParameter="Result" />
</ParseUnsupressedAnalysisIssues>
<Error Text="FxCopAll: Following assemblies had analyzer errors @(FailedAnalyzerFiles)" Condition="'@(FailedAnalyzerFiles->Count())' &gt; 0" Code="2"/>

有一个SARIF SDK可用于处理SARIF文件。它作为一个NuGet包Sarif.Sdk提供,源代码位于Microsoft/Sarif Sdk项目的GitHub上。有一个How-To-document docs/How-To.md,显示如何从磁盘读取一个SARIF文件,并将其反序列化为一个
sarilog
对象;然后,您可以在SARIF对象模型中导航以检查各个结果

在您的情况下,您对结果的“属性包”中的
isSuppressedInSource
属性感兴趣。“操作方法”文档解释了如何检索该属性:

Result result = …;

string isSuppressedInSource = result.GetProperty("isSuppressedInSource");
SARIF规范是,并且有一个链接到更多信息

最后:请注意,在Visual Studio 2015更新2和更新3之间,SARIF格式发生了显著变化。该格式现在是稳定的1.0.0版本

(注意:很抱歉没有提供SDK、NuGet软件包和How to的直接链接。我没有足够的信誉点发布两个以上的链接。)