简体   繁体   English

FXCop自定义规则不会显示在RuleSet中

[英]FXCop Custom Rule does not show up in RuleSet

I followed the steps here to create a new custom rule and add it to the ruleset in VSStudio 2013: 我按照此处的步骤创建了一个新的自定义规则,并将其添加到VSStudio 2013中的规则集:

http://blog.tatham.oddie.com.au/2010/01/06/custom-code-analysis-rules-in-vs2010-and-how-to-make-them-run-in-fxcop-and-vs2008-too/ http://blog.tatham.oddie.com.au/2010/01/06/custom-code-analysis-rules-in-vs2010-and-how-to-make-them-run-in-fxcop-and- VS2008太/

However, despite all my efforts, the custom rule does not show up in the ruleset file. 但是,尽管我付出了很多努力,但自定义规则并未显示在规则集文件中。

If I add the rule in the FXCop Editor, it shows up and analyzes the target project correctly. 如果我在FXCop编辑器中添加规则,它会显示并正确分析目标项目。

This is the Rule File, which is an embedded resource in the project: 这是规则文件,它是项目中的嵌入式资源

<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="PSI Custom FxCop Rules">
<Rule TypeName="EnforceHungarianNotation" Category="PSIRules" CheckId="CR0001">
<Name>Enforce Hungarian Notation</Name>
<Description>Checks fields for compliance with Hungarian notation.</Description>
<Resolution>Field {0} is not in Hungarian notation. Field name should be prefixed with '{1}'.</Resolution>
<MessageLevel Certainty="100">Error</MessageLevel>
<FixCategories>Breaking</FixCategories>
<Url />
<Owner />
<Email />
</Rule>
</Rules>

This is my RuleSet: 这是我的RuleSet:

<?xml version="1.0" encoding="utf-8"?>
    <RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
         <RuleHintPaths>       
             <Path>C:\App\PSI\Development\Source\JHA.ProfitStars.PSI\JHA.ProfitStars  
                   .PSI.FxCop\bin\Debug</Path>
         </RuleHintPaths>
    </RuleSet>

I even tried adding the line below, but now it shows an Unknown rule in the ruleset: 我甚至尝试添加下面的行,但现在它在规则集中显示了一条未知规则:

    <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis"  
         RuleNamespace="Microsoft.Rules.Managed">
         <Rule Id="CR0001" Action="Error" />
    </Rules>

Could someone please help me understand what I am doing wrong here? 请有人帮我理解我在这里做错了什么?

Edited: 编辑:

BaseClass for rules: 规则的BaseClass:

internal abstract class BaseFxCopRule : BaseIntrospectionRule
{
    protected BaseFxCopRule(string ruleName)
        : base(ruleName, "JHA.ProfitStars.PSI.FxCop.Rules", typeof(BaseFxCopRule).Assembly)
    { }
}

Rules Class: 规则类:

internal sealed class EnforceHungarianNotation : BaseFxCopRule
{
    public EnforceHungarianNotation()
        : base("EnforceHungarianNotation")
    { 
    }

    public override TargetVisibilities TargetVisibility
    {
        get
        {
            return TargetVisibilities.NotExternallyVisible;
        }
    }

    public override ProblemCollection Check(Member member)
    {
        Field field = member as Field;
        if (field == null)
        {
            // This rule only applies to fields.
            // Return a null ProblemCollection so no violations are reported for this member.
            return null;
        }

        if (field.IsStatic)
        {
            CheckFieldName(field, s_staticFieldPrefix);
        }
        else
        {
            CheckFieldName(field, s_nonStaticFieldPrefix);
        }

        // By default the Problems collection is empty so no violations will be reported
        // unless CheckFieldName found and added a problem.
        return Problems;
    }
    private const string s_staticFieldPrefix = "s_";
    private const string s_nonStaticFieldPrefix = "m_";

    private void CheckFieldName(Field field, string expectedPrefix)
    {
        if (!field.Name.Name.StartsWith(expectedPrefix, StringComparison.Ordinal))
        {
            Resolution resolution = GetResolution(
              field,  // Field {0} is not in Hungarian notation.
              expectedPrefix  // Field name should be prefixed with {1}.
              );
            Problem problem = new Problem(resolution);
            Problems.Add(problem);
        }
    }
}

Looks like your path is kind of shaky, remove some spacing and unwanted characters: 看起来你的路径有点不稳定,删除一些间距和不需要的字符:

<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
     <RuleHintPaths>       
         <Path>C:\App\PSI\Development\Source\JHA.ProfitStars.PSI\JHA.ProfitStars.PSI.FxCop\bin\Debug</Path>
     </RuleHintPaths>
</RuleSet>

Also adding the rulesdll to Microsoft Visual Studio [Version]\\Team Tools\\Static Analysis Tools\\FxCop\\Rules location would solve the issue of having to use Rulehintpaths. 另外,将rulesdll添加到Microsoft Visual Studio [Version]\\Team Tools\\Static Analysis Tools\\FxCop\\Rules位置将解决必须使用Rulehintpaths的问题。

As I can't detect anything wrong with your custom rules, see if you have selected the option to show all rules: 由于我无法检测到您的自定义规则有任何问题,请查看您是否选择了显示所有规则的选项:

在此输入图像描述

Also, using the following BaseRule might help: 此外,使用以下BaseRule可能会有所帮助:

protected BaseRule(string name)
        : base(

            // The name of the rule (must match exactly to an entry
            // in the manifest XML)
            name,

            // The name of the manifest XML file, qualified with the
            // namespace and missing the extension
            typeof(BaseRule).Assembly.GetName().Name + ".Rules",

            // The assembly to find the manifest XML in
            typeof(BaseRule).Assembly)
    {
    }

Close your solution. 关闭你的解决方案 Use the Source Control Explorer to locate your Rule Set File. 使用源代码管理资源管理器找到您的规则集文件。 Doubleclick onto your ruleset. 双击您的规则集。 The Rule Set Editor now should show all your custom rules. 规则集编辑器现在应该显示所有自定义规则。 If this still doesn't work, try to use a relative path in the Path tag of the RuleHintPaths section. 如果仍然无效,请尝试在RuleHintPaths部分的Path标记中使用相对路径。

Have a look at the LoadFromFile() method of the Microsoft.VisualStudio.CodeAnalysis.dll: 看一下Microsoft.VisualStudio.CodeAnalysis.dll的LoadFromFile()方法:

public static RuleSet LoadFromFile(string filePath, IEnumerable<RuleInfoProvider> ruleProviders)
    {
      RuleSet ruleSet = RuleSetXmlProcessor.ReadFromFile(filePath);
      if (ruleProviders != null)
      {
        string relativePathBase = string.IsNullOrEmpty(filePath) ? (string) null : Path.GetDirectoryName(ruleSet.FilePath);
        Dictionary<RuleInfoProvider, RuleInfoCollection> allRulesByProvider;
        Dictionary<string, IRuleInfo> rules = RuleSet.GetRules((IEnumerable<string>) ruleSet.RuleHintPaths, ruleProviders, relativePathBase, out allRulesByProvider);
        foreach (RuleReference ruleReference in (Collection<RuleReference>) ruleSet.Rules)
        {
          IRuleInfo ruleInfo;
          if (rules.TryGetValue(ruleReference.FullId, out ruleInfo))
          {
            if (ruleInfo.AnalyzerId == ruleReference.AnalyzerId)
              ruleReference.RuleInfo = ruleInfo;
            else
              CATrace.Info("RuleSet.LoadFromFile: Rule {0} was listed under analyzer id {1} in the rule set, but the corresponding IRuleInfo returned analyzer id {2}", (object) ruleReference.FullId, (object) ruleReference.AnalyzerId, (object) ruleInfo.AnalyzerId);
          }
        }
      }
      return ruleSet;
    }

If the relativePathBase is calculated wrong, the rule DLLs will not be found. 如果计算的relativePathBase错误,则将找不到规则DLL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM