c#-如何以编程方式检查解决方案中引用的配置是否正确
我们有一些构建错误,需要手动修复引用。 我希望以编程方式检查是否定义了项目引用而不是dll引用: 因此,检查解决方案中的所有引用,并检查每个项目的引用是否定义正确。这样可以正确配置相关的依赖项c#-如何以编程方式检查解决方案中引用的配置是否正确,c#,dll,reference,msbuild,csproj,C#,Dll,Reference,Msbuild,Csproj,我们有一些构建错误,需要手动修复引用。 我希望以编程方式检查是否定义了项目引用而不是dll引用: 因此,检查解决方案中的所有引用,并检查每个项目的引用是否定义正确。这样可以正确配置相关的依赖项 有人知道现有的解决方案吗?我想要一个验证工具,它将在门控签入之前运行。我已经编写了这样一个工具来处理我们的“.csproj”文件。我的工具在文件夹层次结构中递归下降,处理每个“.csproj”文件,以验证它是否符合我们的标准(例如要求打开代码分析、错误警告、强名称签名等) 不管怎样,我最近重写了很多,使用
有人知道现有的解决方案吗?我想要一个验证工具,它将在门控签入之前运行。我已经编写了这样一个工具来处理我们的“.csproj”文件。我的工具在文件夹层次结构中递归下降,处理每个“.csproj”文件,以验证它是否符合我们的标准(例如要求打开代码分析、错误警告、强名称签名等) 不管怎样,我最近重写了很多,使用Linq to XML来处理文件,结果比七年前我最初编写时简单得多 CSProj处理的核心是由一个类完成的,该类期望将“.CSProj”项目文件的完整路径名作为输入(通过构造函数) 它使用LINQtoXML解析文件的各个部分。看看吧,希望它能让你开始 我还建议在尝试各种XML查询以获取.csproj文件的各种位时使用Linqpad 此代码在某种程度上特定于我们的需求,但它应该为您提供一个起点
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace CreateMSBuildProject
{
/// <summary>Encapsulates a ".csproj" file.</summary>
sealed class CSProj
{
/// <summary>Encapsulates information about a particular build configuration.</summary>
public sealed class BuildConfiguration
{
public BuildConfiguration(XElement configuration)
{
// ReSharper disable PossibleNullReferenceException
OutputPath = configuration.Element(_ns + "OutputPath").Value;
WarningLevel = warningLevel(configuration);
CodeAnalysisRuleset = configuration.Element(_ns + "CodeAnalysisRuleSet").Value;
TreatWarningsAsErrors = isTrue(configuration.Element(_ns + "TreatWarningsAsErrors"));
IsCodeAnalysisEnabled = isTrue(configuration.Element(_ns + "RunCodeAnalysis"));
IsCodeContractsEnabled = isTrue(configuration.Element(_ns + "CodeContractsEnableRuntimeChecking"));
// ReSharper restore PossibleNullReferenceException
}
public bool IsDebug
{
get
{
return (string.Compare(OutputPath, "bin\\debug\\", StringComparison.OrdinalIgnoreCase) == 0);
}
}
public bool IsRelease
{
get
{
return(string.Compare(OutputPath, "bin\\release\\", StringComparison.OrdinalIgnoreCase) == 0);
}
}
static bool isTrue(XElement element) // Defaults to false if element is null.
{
return (element != null) && (string.Compare(element.Value, "true", StringComparison.OrdinalIgnoreCase) == 0);
}
static int warningLevel(XElement element) // Defaults to 4 if not set.
{
var level = element.Element(_ns + "WarningLevel");
if (level != null)
return int.Parse(level.Value);
else
return 4; // Default warning level is 4.
}
public readonly string OutputPath;
public readonly string CodeAnalysisRuleset;
public readonly bool IsCodeAnalysisEnabled;
public readonly bool TreatWarningsAsErrors;
public readonly bool IsCodeContractsEnabled;
public readonly int WarningLevel;
}
/// <summary>Encapsulates information about a referenced assembly.</summary>
public sealed class AssemblyReference
{
public AssemblyReference(XElement reference)
{
Include = reference.Attribute("Include").Value.Split(',')[0]; // Get rid of stuff after the first ","
var hintElem = reference.Element(_ns+"HintPath");
if (hintElem != null)
HintPath = hintElem.Value;
else
HintPath = "";
}
public readonly string HintPath;
public readonly string Include;
}
/// <summary>Constructor.</summary>
public CSProj(string csprojFilePath)
{
if (!isValidProjFilePath(csprojFilePath))
throw new ArgumentOutOfRangeException("csprojFilePath", csprojFilePath, "File does not exist, or filename does not end with '.csproj'.");
// ReSharper disable PossibleMultipleEnumeration
XDocument doc = XDocument.Load(csprojFilePath);
var propertyGroups = getPropertyGroups(doc);
_projectFilePath = csprojFilePath;
_outputType = getOutputType(propertyGroups);
_assemblyName = getAssemblyName(propertyGroups);
_targetFrameworkVersion = getTargetFrameworkVersion(propertyGroups);
_projectDependencies = getProjectDependencies(doc);
_targetFrameworkProfile = getTargetFrameworkProfile(doc);
_xmlDocumentationFiles = getXmlDocumentationFiles(doc);
_buildConfigurations = getBuildConfigurations(doc);
_assemblyReferences = getAssemblyReferences(doc);
_anyStaticCodeAnalysisEnabled = getAnyStaticCodeAnalysisEnabled(doc);
_platformTargets = getPlatformTargets(doc);
// ReSharper restore PossibleMultipleEnumeration
}
#region Properties
/// <summary>The project output type, e.g. "WinExe" or "Library".</summary>
public string OutputType { get { return _outputType; } }
/// <summary>The project's output assembly name.</summary>
public string AssemblyName { get { return _assemblyName; } }
/// <summary>The target framework version, or 0.0 if not set.</summary>
public double TargetFrameworkVersion { get { return _targetFrameworkVersion; } }
/// <summary>The project dependencies - not to be confused with assembly references!</summary>
public IEnumerable<string> ProjectDependencies { get { return _projectDependencies; } }
public IEnumerable<string> XmlDocumentationFiles { get { return _xmlDocumentationFiles; } }
public IEnumerable<BuildConfiguration> BuildConfigurations { get { return _buildConfigurations; } }
public string TargetFrameworkProfile { get { return _targetFrameworkProfile; } }
public IEnumerable<AssemblyReference> AssemblyReferences { get { return _assemblyReferences; } }
public bool AnyStaticCodeAnalysisEnabled { get { return _anyStaticCodeAnalysisEnabled; } }
public string ProjectFilePath { get { return _projectFilePath; } }
public string[] PlatformTargets { get { return _platformTargets; } }
#endregion Properties
//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
static string[] getPlatformTargets(XDocument doc)
{
var result = (from item in doc.Descendants(_ns + "PlatformTarget") select item.Value).ToArray();
if (result.Length > 0)
return result;
else
return new []{"AnyCPU"}; // If "PlatformTarget" is not specified, it defaults to "AnyCPU".
}
static IEnumerable<XElement> getPropertyGroups(XDocument doc)
{
// ReSharper disable PossibleNullReferenceException
return doc.Element(_ns+"Project").Elements(_ns+"PropertyGroup");
// ReSharper restore PossibleNullReferenceException
}
static string getOutputType(IEnumerable<XElement> propertyGroups)
{
return propertyGroups.Elements(_ns+"OutputType").First().Value;
}
static string getAssemblyName(IEnumerable<XElement> propertyGroups)
{
return propertyGroups.Elements(_ns+"AssemblyName").First().Value;
}
static double getTargetFrameworkVersion(IEnumerable<XElement> propertyGroups)
{
var targetFrameworkVersion = propertyGroups.Elements(_ns+"TargetFrameworkVersion").FirstOrDefault();
if (targetFrameworkVersion != null)
return double.Parse(targetFrameworkVersion.Value.Substring(1)); // Skip first character, which is "v"; eg like "v3.5"
else
return 0;
}
static string[] getProjectDependencies(XDocument doc)
{
return
(
from item in doc.Descendants(_ns + "ProjectReference")
select item.Attribute("Include").Value
)
.ToArray();
}
static string getTargetFrameworkProfile(XDocument doc)
{
var targetFrameworkProfile = doc.Descendants(_ns + "TargetFrameworkProfile").FirstOrDefault();
if (targetFrameworkProfile != null)
return targetFrameworkProfile.Value;
else
return "";
}
static string[] getXmlDocumentationFiles(XDocument doc)
{
return
(
from item in doc.Descendants(_ns+"DocumentationFile")
select item.Value
)
.ToArray();
}
static BuildConfiguration[] getBuildConfigurations(XDocument doc)
{
var configGroups = from item in doc.Descendants(_ns+"PropertyGroup")
where item.Descendants(_ns+"OutputPath").Any()
select new BuildConfiguration(item);
return configGroups.ToArray();
}
static AssemblyReference[] getAssemblyReferences(XDocument doc)
{
var references = from item in doc.Descendants(_ns + "Reference")
select new AssemblyReference(item);
return references.ToArray();
}
static bool getAnyStaticCodeAnalysisEnabled(XDocument doc)
{
return doc.Descendants(_ns + "CodeContractsRunCodeAnalysis")
.Where(item => item.Attribute("Condition") == null) // Some of these have a "Condition" attribute, which is OK.
.Any(item => string.Compare(item.Value, "true", StringComparison.OrdinalIgnoreCase) == 0);
}
static bool isValidProjFilePath(string projFilePath)
{
return
(
!string.IsNullOrWhiteSpace(projFilePath)
&& (projFilePath.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) || projFilePath.EndsWith(".vbproj", StringComparison.OrdinalIgnoreCase))
&& File.Exists(projFilePath)
);
}
static readonly XNamespace _ns = "http://schemas.microsoft.com/developer/msbuild/2003";
readonly bool _anyStaticCodeAnalysisEnabled;
readonly string _projectFilePath;
readonly string _outputType;
readonly string _assemblyName;
readonly string _targetFrameworkProfile;
readonly double _targetFrameworkVersion;
readonly string[] _projectDependencies;
readonly string[] _xmlDocumentationFiles;
readonly string[] _platformTargets;
readonly BuildConfiguration[] _buildConfigurations;
readonly AssemblyReference[] _assemblyReferences;
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用System.Xml.Linq;
命名空间CreateMBuildProject
{
///封装“.csproj”文件。
密封级CSProj
{
///封装有关特定生成配置的信息。
公共密封类构建配置
{
公共构建配置(XElement配置)
{
//ReSharper禁用PossibleNullReferenceException
OutputPath=configuration.Element(_ns+“OutputPath”).Value;
警告级别=警告级别(配置);
CodeAnalysisRuleset=configuration.Element(_ns+“CodeAnalysisRuleset”).Value;
TreatWarningsAsErrors=isTrue(configuration.Element(_ns+“TreatWarningsAsErrors”);
IsCodeAnalysisEnabled=isTrue(configuration.Element(_ns+“RunCodeAnalysis”);
IsCodeContractsEnabled=isTrue(configuration.Element(_ns+“CodeContractsEnableRuntimeChecking”);
//ReSharper还原可能的NullReferenceException
}
公共图书馆
{
得到
{
返回(string.Compare(OutputPath,“bin\\debug\\”,StringComparison.OrdinalIgnoreCase)==0);
}
}
公共图书馆
{
得到
{
返回(string.Compare(OutputPath,“bin\\release\\”,StringComparison.OrdinalIgnoreCase)==0);
}
}
静态bool isTrue(XElement元素)//如果元素为null,则默认为false。
{
返回(element!=null)&&(string.Compare(element.Value,“true”,StringComparison.OrdinalIgnoreCase)==0);
}
static int warningLevel(XElement元素)//如果未设置,则默认为4。
{
var级别=元素。元素(_ns+“警告级别”);
如果(级别!=null)
返回int.Parse(level.Value);
其他的
return 4;//默认警告级别为4。
}
公共只读字符串输出路径;
公共只读字符串CodeAnalysisRuleset;
已启用公共只读bool IsCodeAnalysisEnabled;
公共只读布尔处理警告ASERRORS;
已启用公共只读布尔码;
公共只读警告级别;
}
///封装有关引用程序集的信息。
公共密封类集合引用
{
公共程序集引用(XElement引用)
{
Include=reference.Attribute(“Include”).Value.Split(“,”)[0];//去掉第一个“,”后面的内容
var hintElem=参考元素(_ns+“HintPath”);
if(hintElem!=null)
HintPath=暗示值;
其他的
HintPath=“”;
}
公共只读字符串HintPath;
公共只读字符串包括;
}
///构造器。
公共CSProj(字符串csprojFilePath)
{
如果(!isValidProjFilePath(csprojFilePath))
抛出新ArgumentOutOfRangeException(“csprojFilePath”,csprojFilePath,“文件不存在,或文件名不以“.csproj.”结尾”);
//ReSharper禁用可能的多重枚举
XDocument doc=XDocument.Load(csprojFilePath);
var propertyGroups=getPropertyGroups(doc);
_projectFilePath=csprojFilePath;
_outputType=getOutputType(PropertyGroup);
_assemblyName=getAssemblyName(PropertyGroup);
_targetFrameworkVersion=getTargetFrameworkVersion(PropertyGroup);
_projectDependencies=getProjectDependencies(文档);
_targetFrameworkProfile=getTargetFrameworkProfile(文档);
_xmlDocumentationFiles=getXmlDocumentationFiles(doc);
_buildConfigurations=getBuildConfigurations(doc);
_assemblyReferences=getAssemblyReferences(文档);
_anyStaticCodeAnalysisEnabled=getAnyStaticCodeAnalysisEnabled(文档);
_platformTargets=getPlatformTarget