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

PowerShell检测IIS应用.NET版本时的反射程序集加载错误排查

问题分析与修复方案

咱们先拆解你遇到的两个错误,然后给出修复后的PowerShell脚本:

错误1:FileLoadException(程序集重复加载)

原因

ReflectionOnlyLoadFrom会把程序集加载到当前PowerShell的AppDomain中,一旦某个程序集(比如WebGrease.dll)从某个路径加载过,后续再从其他路径加载同名/同标识的程序集时,.NET就会抛出这个错误——因为同一个AppDomain不允许从不同位置加载相同的程序集。

错误2:BadImageFormatException(非.NET程序集加载失败)

原因

epengine.dll是原生Windows DLL(不是.NET程序集),它没有.NET程序集必需的清单结构,所以ReflectionOnlyLoadFrom无法识别它,自然会报错。


修复后的脚本

我调整了脚本逻辑,用更安全的方式获取.NET版本,同时避免上述两个错误:

$Apps = Get-WebApplication
foreach($App in $Apps) {
    $binLocation = Join-Path -Path $App.physicalPath -ChildPath "bin"
    if (-not (Test-Path -Path $binLocation)) {
        Write-Host "No bin folder found for app: $($App.Path)"
        continue
    }

    # 获取bin目录下所有dll文件
    $dlls = Get-ChildItem -Path $binLocation -Filter "*.dll" -File

    # 存储唯一的.NET运行时版本
    $runtimeVersions = New-Object System.Collections.Generic.HashSet[String]

    foreach($dll in $dlls) {
        try {
            # 仅读取程序集元数据,不加载到AppDomain,避免重复加载冲突
            $assemblyName = [System.Reflection.AssemblyName]::GetAssemblyName($dll.FullName)
            # 获取CLR运行时版本(比如v4.0.30319)
            $runtimeVersion = $assemblyName.ImageRuntimeVersion
            if ($runtimeVersion) {
                $runtimeVersions.Add($runtimeVersion) | Out-Null
            }
        }
        catch [System.BadImageFormatException] {
            # 跳过非.NET原生DLL,可根据需要取消注释开启日志
            # Write-Host "Skipping non-.NET DLL: $($dll.FullName)"
            continue
        }
        catch {
            # 捕获其他意外错误
            Write-Warning "Error processing $($dll.FullName): $_"
            continue
        }
    }

    # 输出结果
    Write-Host "`n=== Web Application: $($App.Path) ==="
    Write-Host "Physical Path: $($App.physicalPath)"
    if ($runtimeVersions.Count -gt 0) {
        Write-Host "Used .NET Runtime Versions:"
        $runtimeVersions | ForEach-Object { Write-Host "  - $_" }
    }
    else {
        Write-Host "No .NET DLLs found or no valid runtime versions detected."
    }
}

关键改进点

  1. 用AssemblyName::GetAssemblyName()替代ReflectionOnlyLoadFrom:
    这个方法只读取DLL文件的元数据,不会将程序集加载到当前AppDomain,彻底解决了重复加载的冲突问题,性能也更优。
  2. 异常捕获处理:
    • 捕获BadImageFormatException,自动跳过非.NET原生DLL;
    • 添加通用异常捕获,避免单个DLL的错误导致整个脚本中断。
  3. 路径优化:
    用Join-Path处理路径拼接,避免手动拼接时的格式错误;新增Test-Path检查bin目录是否存在,减少无效操作。

内容的提问来源于stack exchange,提问作者Tourius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:40:18