安装dotnet-9.0-sdk后PowerShell解析SLN脚本抛出异常
解决MSBuild加载System.Memory版本不匹配问题
问题背景
将Visual Studio 2022 Build Tools版本从17.8.3更新至17.13.1,并安装.NET 9 SDK后,运行以下PowerShell脚本时出现程序集加载错误:
Add-Type -Path "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\Microsoft.Build.dll" [Microsoft.Build.Construction.SolutionFile]::Parse('C:/Test/Test.sln')
错误信息:
Exception calling "Parse" with "1" argument(s): "Could not load file or assembly 'System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified." At C:\Test\run.ps1:2 char:1 + [Microsoft.Build.Construction.SolutionFile]::Parse('C:/Test/Test ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : FileNotFoundException
更换不同版本的VS(2019/2017)或Microsoft.Build.dll(17.11.4/17.13.9)后问题仍存在,推测是.NET 9 SDK安装后程序集绑定优先级变化导致。
原因分析
.NET 9 SDK自带的System.Memory版本高于MSBuild依赖的4.0.1.1版本,直接加载Microsoft.Build.dll时,CLR无法自动处理版本重定向,导致找不到指定版本的程序集。
解决办法
1. 添加程序集绑定重定向
通过临时配置文件让CLR自动将旧版本System.Memory的请求重定向到系统中已存在的新版本:
# 创建临时程序集重定向配置文件 $tempConfig = "$env:TEMP\msbuild_runtime_config.xml" @' <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.2" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration> '@ | Out-File $tempConfig -Encoding UTF8 # 让PowerShell使用该配置文件 $env:COMPLUS_ApplicationConfigurationFile = $tempConfig # 加载MSBuild并解析解决方案 Add-Type -Path "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\Microsoft.Build.dll" $solution = [Microsoft.Build.Construction.SolutionFile]::Parse('C:/Test/Test.sln') # 可在此添加解决方案操作逻辑 # 清理临时文件和环境变量 Remove-Item $tempConfig -Force Remove-Item Env:COMPLUS_ApplicationConfigurationFile
2. 使用MSBuild命令行替代直接加载DLL
若无需在PowerShell中直接操作SolutionFile对象,建议用MSBuild命令行工具获取解决方案信息,规避程序集加载问题:
# 获取解决方案中的项目列表 msbuild "C:/Test/Test.sln" /t:GetProjectList /nologo /v:quiet
或使用dotnet msbuild(兼容.NET SDK风格项目):
dotnet msbuild "C:/Test/Test.sln" /t:GetProjectList /nologo /v:quiet
3. 显式加载正确版本的System.Memory.dll
先加载系统中已存在的高版本System.Memory.dll,再加载Microsoft.Build.dll:
# 路径根据实际.NET 9 SDK安装位置调整 Add-Type -Path "C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.0\System.Memory.dll" # 加载MSBuild Add-Type -Path "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\Microsoft.Build.dll" $solution = [Microsoft.Build.Construction.SolutionFile]::Parse('C:/Test/Test.sln')
4. 使用dotnet sln命令操作解决方案
若仅需执行基础的解决方案操作(如列出项目、添加/移除项目),直接使用.NET CLI的dotnet sln命令更简洁:
# 列出解决方案中的所有项目 dotnet sln "C:/Test/Test.sln" list
内容的提问来源于stack exchange,提问作者Yola
相关产品推荐
相关产品推荐

