【问题标题】:Powershell GetCustomAttributes failing with could not load file or assemblyPowershell GetCustomAttributes 失败,无法加载文件或程序集
【发布时间】:2020-01-22 15:28:01
【问题描述】:

ps1 脚本应该循环遍历 /bin 文件夹中的程序集,提取属性,然后构造一个带有匹配项的 json 文件。这对 99% 的 DLLS 都有效。

但一个 DLL 是在构建时引用了一个旧程序集

Exception calling "GetCustomAttributes" with "1" argument(s): "Could not load file or assembly
'Telerik.Sitefinity.Frontend, Version=12.2.7200.0, Culture=neutral, PublicKeyToken=b28c218413bdf563' or one of its
dependencies. The system cannot find the file specified."

文件夹中的版本是12.2.7225.0

所以这个程序集基本跳过了……

当 webapp 运行时这不是问题,因为 web.config 程序集绑定只是很好地处理版本不匹配,但在 powershell 中,它正在失败。

param(
    [Parameter(Mandatory=$true)]
    [string]$binariesDirectory
)

$assemblies = Get-ChildItem $binariesDirectory -Filter *.dll
$controllerAssemblies = @()

foreach ($assembly in $assemblies) {
    $loadedAssembly = [System.Reflection.Assembly]::LoadFrom($assembly.FullName)

    #THIS IS THE TEST 
    if($assembly.Name -eq "RandomSiteControlsMVC.dll"){
        Write-Output "Custom Attributes for " + $assembly.Name;
        #THIS IS WHAT FAILS
        $result = [reflection.customattributedata]::GetCustomAttributes($loadedAssembly)
        Write-Output $result;
    }

    #$loadedAssembly.CustomAttributes just returns nothing in the case of that DLL
    if ($loadedAssembly.CustomAttributes | ? { $_.AttributeType.FullName -eq "Telerik.Sitefinity.Frontend.Mvc.Infrastructure.Controllers.Attributes.ControllerContainerAttribute" -or $_.AttributeType.FullName -eq "Telerik.Sitefinity.Frontend.Mvc.Infrastructure.Controllers.Attributes.ResourcePackageAttribute"}) {
        $controllerAssemblies += $assembly.Name
    }
}

$controllerAssemblies | ConvertTo-Json -depth 100 | Set-Content "$binariesDirectory\ControllerContainerAsembliesLocation.json" -Force

有没有什么神奇的方法可以在不抛出异常的情况下正常工作?

【问题讨论】:

    标签: powershell assemblies


    【解决方案1】:

    使用 Try Catch 语句捕获错误。 然后,在 catch 语句中,您可以执行导致 dll 无法记录的操作,或者......根本没有。

    例如,在您的情况下,由于您处于循环中,因此如果程序集的名称是您不关心的名称,则可以添加 Continue 语句,或者如果它不同,则返回错误dll。像这样的:

    try {
        $loadedAssembly = [System.Reflection.Assembly]::LoadFrom('blurb.dll') 
    }
    catch {
        # Update accordingly to your needs
        if ($assembly.Name -eq "Telerik.Sitefinity.Frontend.dll") {
            # Let's stop there and go to the next dll in the loop
            Continue 
        }
        else {
            # Do something if the dll that failed to load is another dll than the one you don't care
            Write-Error $_ 
        }
    }
    

    【讨论】:

    • 是的,这就是答案...我处理错误,如果它是针对 Telerik.Sitefinity 命名空间的绑定错误,我只需添加它以确保安全。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    相关资源
    最近更新 更多