我想使用Windows PowerShell 5.1 脚本中的NDepend API,但由于 Windows PowerShell 无法处理具有相同名称但不同大小写的属性,因此可能无法实现。
以下是目前为止可以运行的 PowerShell 代码:
using namespace NDepend
Set-StrictMode -Version Latest
$AssList = "NDepend.API", "NDepend.Core", "NDepend.Platform.DotNet", "NDepend.Analysis", "NDepend.Platform.DotNet.NetFx", "NDepend.UI.NetFx"
$AssList.ForEach{
$AssPfad = Join-Path -Path "D:\Program Files\NDepend\Lib" -ChildPath "$_.dll"
Add-Type -Path $AssPfad
}
$ndprojPath = "D:\Test1234.ndproj"
# Still using NDepend in the namespace for clarity (although it is not necessary)
$ndprojPathAbsolute = [NDepend.Path.PathHelpers]::ToAbsoluteFilePath($ndprojPath)
$ndProvider = [NDepend.NDependServicesProvider]::new()
$ndManager = $ndProvider.ProjectManager
$project = $ndManager.LoadProject($ndprojPathAbsolute)
$outputDirPath = Join-Path -Path $PSScriptRoot -ChildPath "OutputDir"
$project.Properties.OutputDir = [NDepend.Path.PathHelpers]::ToDirectoryPath($outputDirPath)
$analysisResult = [NDepend.Analysis.ExtensionMethodsProjectAnalysis]::RunAnalysisAndBuildReport($project)
$ndCodebase = $analysisResult.CodeBase
输出$ndCodebase导致错误
format-default : # The field or property "F18r" for type "a.QHkY" differs only in letter casing from the field or property "f18R". The type must be Common Language Specification (CLS) compliant
脚本的其余部分可以运行并将输出分析结果:
$Issues = [Analysis.ExtensionMethodsProjectAnalysis]::ComputeIssues($analysisResult)
$ndIssuesSet = $Issues
$ndIssuesSet.AllRules
目前我不确定如何避免这个错误。
PS:只有获得构建许可证才可复制该代码。
更新:感谢mklement0的评论和建议,我能够反思导致错误的属性
$Ass = [AppDomain]::CurrentDomain.GetAssemblies().Where{$_.GetName().Name -eq "NDepend.Core"}[0]
$t = $ass.gettype("a.QHkY", $True)
# Just for information purpose
$t.GetProperties().Where{$_.Name -match "f18r"}
# Not getting this property with reflection due to casing?
$PropInfo1 = $ass.gettype("a.QHkY", $True).GetProperty("f18r", [System.Reflection.BindingFlags]::IgnoreCase)
# Getting this property
$PropInfo2 = $ass.gettype("a.QHkY", $True).GetProperty("F18r")
# No value since $PropInfo1 is $null
$PropInfo1.GetValue($analysisResult.CodeBase)
# Getting a value
$PropInfo2.GetValue($analysisResult.CodeBase)
但由于我想要AsCodeBase属性的值:
# Get the value of the AsCodeBase property
$PropInfo = $ass.gettype("a.QHkY", $True).GetProperty("AsCodeBase")
$Value = $PropInfo.GetValue($ndCodebase)
$Value
我会得到相同的格式默认错误,然后又回到原点。$Value包含CodeBase对象的值,但看起来 PowerShell 格式化程序导致了错误。
实际上,PowerShell 明确检查 .NET 类型是否具有名称彼此大小写不同
F18r
的成员(例如vs. );当尝试访问任何给定类型的成员时,f18r
任何此类类型根据定义都不符合 CLS 。在Windows PowerShell中,以及至少到v7.4.x的版本中,在PowerShell (Core) 7中,遇到属性或字段名称的大小写变化会导致(语句终止)错误(.NET 异常)(而对于方法,这种大小写变化是可以默默容忍的,当其中一个方法被调用时,您无法可预测地调用给定的变体)。
GitHub 问题 #10303 是一个解决此问题的提议,但尚未有人站出来实施它。
.F18r
和的尝试都会成功并匹配完全匹配大小写.f18r
的属性/字段- 但不完全匹配的变体仍会报告错误,例如。.F18R
解决方法:
目前,避免这种情况下出现错误的唯一方法是在访问具有大小写变化的属性和字段成员时使用 .NET反射。
$ndCodebase
警告:
您需要知道给定实例的具体类型才能使用反射解决方法,因为必须在类型上调用反射方法才能避免错误 -接口类型可能会或可能不会起作用(而调用实例上的任何成员- 包括
.GetType()
方法 -总是会触发当前的错误)。在您的情况下,文档仅将属性值类型表达为接口,并且属性值实现的接口
.CodeBase
似乎不包含触发错误的大小写变体成员。但是,您应该能够通过内在
.pstypenames
属性推断出具体类型的完整类型名称:使用完整的具体类型,您可以使用反射来访问
.F18r
字段/属性值(大小写完全一致),如下所示,假设它是一个属性(如果它是一个字段,则替换.GetProperty()
为.GetField()
: