PowerShell 7.3.1调用NLog.dll时偶发不可回收程序集引用异常求助
解决PowerShell 7.3.1中"A non-collectible assembly may not reference a collectible assembly"异常
问题场景
在PowerShell 7.3.1中运行脚本时偶尔触发以下异常,Visual Studio Code 1.74.2或pwsh提示符下均会出现:
A non-collectible assembly may not reference a collectible assembly. StackTrace: at ProcessItems, C:\git\PerfAndMon-Tools\Scripts\AppDynamics\ServerChecks\Modules\UpdateDnaPathsFunctions.psm1: line 210 at <ScriptBlock><Process>, C:\git\PerfAndMon-Tools\Scripts\AppDynamics\ServerChecks\UpdateDNAPaths.ps1: line 227 at <ScriptBlock>, <No file>: line 1
环境信息
- 直接加载的.NET程序集:NLog 4.7.10.13013(通过
[Reflection.Assembly]::LoadFile($DllPath)加载) - 操作系统:Windows 10 Enterprise 21H2(内部版本19044.2364)
- 使用的其他.NET组件:System.Diagnostics.Stopwatch、System.Text.StringBuilder、System.Collections.ArrayList
- 补充:NLog模块的Pester单元测试从未触发该异常
可能的解决方向
1. 替换程序集加载方式
避免使用[Reflection.Assembly]::LoadFile,改用PowerShell原生的Add-Type -Path $DllPath加载NLog程序集。LoadFile可能将程序集标记为可回收(collectible),后续非可回收程序集引用它时会触发异常。
2. 检查NLog依赖的程序集
NLog可能依赖其他.NET程序集,这些依赖集可能被以可回收方式加载。可通过以下命令查看依赖情况:
$nlogAssembly = [Reflection.Assembly]::LoadFile($DllPath) $nlogAssembly.GetReferencedAssemblies() | Format-Table Name, Version
若发现异常依赖,尝试用Add-Type手动加载这些依赖集。
3. 避免程序集重复加载
脚本运行中重复加载NLog可能导致可回收与非可回收版本冲突,加载前可先检查程序集是否已存在:
if (-not [AppDomain]::CurrentDomain.GetAssemblies().Where({$_.GetName().Name -eq 'NLog'}, 'First')) { Add-Type -Path $DllPath }
4. 升级NLog版本
NLog 4.7.10属于较旧版本,升级到最新稳定版(如5.x系列),新版本可能修复了与.NET Core/PowerShell 7兼容性相关的程序集加载问题。
5. 检查动态代码编译逻辑
若脚本中使用Add-Type -TypeDefinition动态编译代码,这类代码默认是可回收的。如果动态代码引用了NLog(非可回收),会触发异常。需调整编译参数,标记为非可回收:
$compilerParams = New-Object System.CodeDom.Compiler.CompilerParameters $compilerParams.GenerateInMemory = $true # 禁用可回收特性 $compilerParams.GenerateExecutable = $false Add-Type -TypeDefinition $yourDynamicCode -CompilerParameters $compilerParams -ReferencedAssemblies $DllPath
内容的提问来源于stack exchange,提问作者Robert Bratton
相关产品推荐
相关产品推荐

