在Windows PowerShell 5.1中调用NDepend API遇CLS大小写兼容错误
在Windows PowerShell 5.1中调用NDepend API的大小写属性问题
我希望在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" # 为了清晰仍保留NDepend命名空间(虽然没必要) $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:该问题仅能通过构建许可证复现。
更新1:通过反射定位引发错误的属性
感谢mklement0的评论与建议,我已通过反射找到引发错误的属性:
$Ass = [AppDomain]::CurrentDomain.GetAssemblies().Where{$_.GetName().Name -eq "NDepend.Core"}[0] $t = $ass.gettype("a.QHkY", $True) # 仅用于信息查看 $t.GetProperties().Where{$_.Name -match "f18r"} # 无法通过忽略大小写的反射获取该属性? $PropInfo1 = $ass.gettype("a.QHkY", $True).GetProperty("f18r", [System.Reflection.BindingFlags]::IgnoreCase) # 可以获取该属性 $PropInfo2 = $ass.gettype("a.QHkY", $True).GetProperty("F18r") # 由于$PropInfo1为null,无法获取值 $PropInfo1.GetValue($analysisResult.CodeBase) # 可以获取值 $PropInfo2.GetValue($analysisResult.CodeBase)
更新2:直接获取CodeBase属性值仍报错
当我尝试获取CodeBase属性的值时,还是会遇到相同的format-default错误:
# 获取CodeBase属性的值 $PropInfo = $ass.gettype("a.vHLF", $True).GetProperty("CodeBase") $Value = $PropInfo.GetValue($ndCodebase) $Value
$Value确实包含CodeBase对象的值,但似乎是PowerShell格式化程序触发了错误。
更新3:嵌入C#的解决方案(但过于繁琐)
正如mklement0所建议,问题的核心是需要将对象“重新封装”为自定义类型并保留所需属性。我通过在PowerShell脚本中嵌入C#代码实现了该方案,但这种方式太过繁琐:
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:\Test.ndproj" # 为了清晰仍保留NDepend命名空间(虽然没必要) $ndprojPathAbsolute = [Path.PathHelpers]::ToAbsoluteFilePath($ndprojPath) $ndProvider = [NDepend.NDependServicesProvider]::new() $ndManager = $ndProvider.ProjectManager $project = $ndManager.LoadProject($ndprojPathAbsolute) $analysisResult = [NDepend.Analysis.ExtensionMethodsProjectAnalysis]::RunAnalysis($project) # 在C#中进行反射操作,避免直接在PowerShell中处理CodeBase对象 $CSCode = @" using NDepend.Analysis; using NDepend.Issue; using NDepend.CodeModel; using System; using System.Collections.Generic; using System.Linq; public class CodeBaseInfo { public ICodeBase CodeBase { get; set; } public int NbLinesOfCode { get; set; } public CodeBaseInfo(IAnalysisResult analysisResult) { this.CodeBase = analysisResult.CodeBase; var ass = AppDomain.CurrentDomain.GetAssemblies().Where(a=>a.GetName().Name == "NDepend.Core").First(); var propInfo = ass.GetType("a.vHLF").GetProperty("CodeBase"); var propValue = propInfo.GetValue(analysisResult); propInfo = ass.GetType("a.QHkY").GetProperty("NbLinesOfCode"); this.NbLinesOfCode = Convert.ToInt32(propInfo.GetValue(propValue)); } // 会触发格式错误——仅作演示用 public ICodeBase GetCodeBase() { return this.CodeBase; } public ICodeBaseView GetApplication() { return this.CodeBase.Application; } public int GetNbLinesOfCode() { return this.NbLinesOfCode; } } "@ # 请确认NDepend.API.dll的路径 Add-Type -TypeDefinition $CSCode -ReferencedAssemblies "D:\Program Files\NDepend\Lib\NDepend.API.dll", "netstandard" $CodeBaseInfo = [CodeBaseInfo]::new($analysisResult) # 会触发相同的格式错误 # $CodeBaseInfo.CodeBase # 以下代码可正常运行... $CodeBaseInfo.GetApplication() $CodeBaseInfo.GetNbLinesOfCode()
内容的提问来源于stack exchange,提问作者Peter M.
相关产品推荐
相关产品推荐

