我按照此处的步骤创建了一个新的自定义规则,并将其添加到VSStudio 2013中的规则集中:
但是,尽管我付出了很多努力,但自定义规则并未显示在规则集文件中。
如果我在FXCop编辑器中添加规则,它会显示并正确分析目标项目。
这是规则文件,它是项目中的嵌入资源:
<?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>
这是我的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>
我甚至尝试添加以下行,但现在它在规则集中显示未知规则:
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis"
RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CR0001" Action="Error" />
</Rules>
有人可以帮我理解我在这里做错了吗?
编辑:
规则的BaseClass:
internal abstract class BaseFxCopRule : BaseIntrospectionRule
{
protected BaseFxCopRule(string ruleName)
: base(ruleName, "JHA.ProfitStars.PSI.FxCop.Rules", typeof(BaseFxCopRule).Assembly)
{ }
}
规则类:
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);
}
}
}
答案 0 :(得分:0)
看起来你的路径有点不稳定,删除一些间距和不需要的字符:
<?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>
同时将rulesdll添加到Microsoft Visual Studio [Version]\Team Tools\Static Analysis Tools\FxCop\Rules
位置可以解决必须使用Rulehint路径的问题。
由于我无法检测到您的自定义规则有任何问题,请查看您是否选择了显示所有规则的选项:
此外,使用以下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)
{
}
答案 1 :(得分:0)
关闭解决方案。使用源代码管理资源管理器找到您的规则集文件。双击您的规则集。规则集编辑器现在应该显示所有自定义规则。如果仍然无效,请尝试在RuleHintPaths部分的Path标记中使用相对路径。
查看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;
}
如果计算出relativePathBase错误,则找不到规则DLL。