You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 09:35:04