Отвечу на свой вопрос на случай, если кто-то еще столкнется с этим. Я нашел решение, но честно предупреждаю, это не очень красиво.
- Я взял пример решения C# с Github, загрузил его в Visual Studio и использовал NuGet для установки анализаторов FxCop. Это установило анализаторы и изменило файлы .csproj решения, чтобы они ссылались на них. В моем случае я нашел копию анализаторов в C: \ users \ myname.nuget \ packages.
- Я сравнил измененные файлы .csproj с оригиналами, чтобы увидеть, какие изменения были внесены во время монтаж. Я рекомендую всем, кто следит за мной, провести это сравнение самостоятельно, но в моем случае изменения были следующими:
- Пять элементов импорта вверху, ссылающихся на различные файлы .props.
- Пустой элемент NuGetPackageImportStamp.
- Две новые группы элементов внизу, первая содержит единственный элемент с именем «None», вторая содержит различные элементы Analyzer, ссылающиеся на .dlls.
- Новая цель, гарантирующая, что файлы .props действительно существуют .
- Я написал программу C#, которая взяла произвольное решение, нашла все файлы .csproj внутри и вручную добавила к ним новые элементы XML. Я пропустил одноэлементную ItemGroup и Target без каких-либо проблем.
В идеале вы бы тогда (из той же C# программы) вызывали msbuild в файле .sln, сохраняя все совпадения выходной строки регулярное выражение "): предупреждение CA \ d \ d \ d \ d:" (т.е. предупреждения, созданные FxCop), и восстановить исходные файлы .csproj. Я делал это вручную. Вот код для манипуляции XML:
static void addAnalyzersToCsProj(string file)
{
string[] packages = new string[]
{
@"C:\users\myname\.nuget\packages\microsoft.codeanalysis.fxcopanalyzers\3.0.0\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props",
@"C:\users\myname\.nuget\packages\microsoft.codeanalysis.versioncheckanalyzer\3.0.0\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props",
@"C:\users\myname\.nuget\packages\microsoft.codequality.analyzers\3.0.0\build\Microsoft.CodeQuality.Analyzers.props",
@"C:\users\myname\.nuget\packages\microsoft.netcore.analyzers\3.0.0\build\Microsoft.NetCore.Analyzers.props",
@"C:\users\myname\.nuget\packages\microsoft.netframework.analyzers\3.0.0\build\Microsoft.NetFramework.Analyzers.props",
};
var root = XElement.Load(file);
var ns = "";
for (var i = 0; i < 5; i++)
{
XElement packageImport = new XElement(ns+"Import");
packageImport.SetAttributeValue("Project", packages[i]);
string condition = "Exists('" + packages[i] + "')";
packageImport.SetAttributeValue("Condition", condition);
root.AddFirst(packageImport);
}
var propertyGroup = root.Descendants(ns + "PropertyGroup").First();
var stamp = new XElement(ns+"NuGetPackageImportStamp", "");
propertyGroup.Elements().Last().AddAfterSelf(stamp);
var newGroup = new XElement(ns+"ItemGroup");
// do we need to include the "None Include="packages.config"" thing?
string[] libraries = new string[]
{
@"C:\users\myname\.nuget\packages\microsoft.codeanalysis.versioncheckanalyzer\3.0.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.VersionCheckAnalyzer.resources.dll",
@"C:\users\myname\.nuget\packages\microsoft.codeanalysis.versioncheckanalyzer\3.0.0\analyzers\dotnet\Microsoft.CodeAnalysis.VersionCheckAnalyzer.dll",
@"C:\users\myname\.nuget\packages\microsoft.codequality.analyzers\3.0.0\analyzers\dotnet\cs\Humanizer.dll",
@"C:\users\myname\.nuget\packages\microsoft.codequality.analyzers\3.0.0\analyzers\dotnet\cs\Microsoft.CodeQuality.Analyzers.dll",
@"C:\users\myname\.nuget\packages\microsoft.codequality.analyzers\3.0.0\analyzers\dotnet\cs\Microsoft.CodeQuality.CSharp.Analyzers.dll",
@"C:\users\myname\.nuget\packages\microsoft.netcore.analyzers\3.0.0\analyzers\dotnet\cs\Microsoft.NetCore.Analyzers.dll",
@"C:\users\myname\.nuget\packages\microsoft.netcore.analyzers\3.0.0\analyzers\dotnet\cs\Microsoft.NetCore.CSharp.Analyzers.dll",
@"C:\users\myname\.nuget\packages\microsoft.netframework.analyzers\3.0.0\analyzers\dotnet\cs\Microsoft.NetFramework.Analyzers.dll",
@"C:\users\myname\.nuget\packages\microsoft.netframework.analyzers\3.0.0\analyzers\dotnet\cs\Microsoft.NetFramework.CSharp.Analyzers.dll",
};
foreach (string lib in libraries)
{
XElement analyzer = new XElement(ns+"Analyzer");
analyzer.SetAttributeValue("Include", lib);
newGroup.AddFirst(analyzer);
}
Console.WriteLine(root.Elements().Last().ToString());
root.Elements().Last().AddAfterSelf(newGroup);
root.Save(file, SaveOptions.None);
// and do we need to include the error checking target?
}
Насколько я могу судить, это работает, хотя я понятия не имею, что произойдет, если вы попытаетесь сделать это с решением, которое уже анализаторы установлены нормально.
Запуск анализаторов FxCop через msbuild кажется неэффективным, но я не нашел лучшего способа сделать это. Похоже, они созданы для работы только в компиляторе. Надеюсь, я ошибаюсь, и я все равно буду признателен за любой совет о том, как запускать анализаторы автоматически без необходимости сборки всего проекта.