多.NET版本C#解决方案中Visual Studio测试资源管理器异常问题
问题:Visual Studio测试资源管理器运行.NET 8单元测试失败,命令行执行正常
我们开发Autodesk产品插件,为兼容旧版本软件采用同时支持.NET Framework 4.7与.NET 8的混合C#解决方案,已将旧项目转为SDK风格,通过Directory.Build.props统一配置目标框架。目前解决方案的构建、调试及Git流水线部署均正常,但单元测试在Visual Studio测试资源管理器中运行失败,命令行执行则完全正常。错误信息包括:缺失System.Runtime引用、StackOverflowException、无法加载测试平台类型、无法计算目标框架名称等。将测试项目的TargetFramework改为net4.7后可正常运行,现需排查问题原因并找到解决办法。
相关配置代码
Directory.Build.props
<Project> <PropertyGroup> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <BaseIntermediateOutputPath>$(MSBuildProjectDirectory)\out\$(MSBuildProjectName)\obj</BaseIntermediateOutputPath> <IntermediateOutputPath>$(BaseIntermediateOutputPath)\$(Configuration)</IntermediateOutputPath> <OutputPath>bin\$(Configuration)</OutputPath> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> </PropertyGroup> <PropertyGroup> <LangVersion>preview</LangVersion> <Nullable>enable</Nullable> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> </PropertyGroup> <PropertyGroup> <AcadVersion Condition="$(Configuration.Contains('2021'))">2021</AcadVersion> <AcadVersion Condition="$(Configuration.Contains('2022'))">2022</AcadVersion> <AcadVersion Condition="$(Configuration.Contains('2023'))">2023</AcadVersion> <AcadVersion Condition="$(Configuration.Contains('2024'))">2024</AcadVersion> <AcadVersion Condition="$(Configuration.Contains('2025'))">2025</AcadVersion> </PropertyGroup> <PropertyGroup> <NetVersion>80</NetVersion> <NetVersion Condition="$(Configuration.Contains('Framework'))">47</NetVersion> <NetVersion Condition="$(Configuration.Contains('2021'))">47</NetVersion> <NetVersion Condition="$(Configuration.Contains('2022'))">47</NetVersion> <NetVersion Condition="$(Configuration.Contains('2023'))">47</NetVersion> <NetVersion Condition="$(Configuration.Contains('2024'))">47</NetVersion> </PropertyGroup> <PropertyGroup Condition="$(Configuration.Contains('Debug'))"> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> <DefineConstants>DEBUG;TRACE</DefineConstants> </PropertyGroup> <PropertyGroup Condition="$(Configuration.Contains('Staging'))"> <DebugSymbols>true</DebugSymbols> <DefineConstants>STAGING;TRACE</DefineConstants> <DebugType>full</DebugType> </PropertyGroup> <PropertyGroup Condition="$(Configuration.Contains('Release'))"> <DebugType>none</DebugType> <Optimize>true</Optimize> <DefineConstants>TRACE</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(NetVersion)' == '47'"> <TargetFramework>net47</TargetFramework> <PreBuildEvent>RD /S /Q "$(ProjectDir)obj"</PreBuildEvent> </PropertyGroup> <PropertyGroup Condition="'$(NetVersion)' == '80'"> <TargetFramework>net8.0-windows</TargetFramework> </PropertyGroup> <PropertyGroup Condition="'$(AcadVersion)' == '2021'"> <DefineConstants>$(DefineConstants);ACAD2021</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(AcadVersion)' == '2022'"> <DefineConstants>$(DefineConstants);ACAD2022</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(AcadVersion)' == '2023'"> <DefineConstants>$(DefineConstants);ACAD2023</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(AcadVersion)' == '2024'"> <DefineConstants>$(DefineConstants);ACAD2024</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(AcadVersion)' == '2025'"> <DefineConstants>$(DefineConstants);ACAD2025</DefineConstants> </PropertyGroup> <ItemGroup Condition="'$(AcadVersion)' != ''"> <Reference Include="accoremgd"> <HintPath>..\Desktop.References.Autodesk\AutoCAD\$(AcadVersion)\AcCoreMgd.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="Acdbmgd"> <HintPath>..\Desktop.References.Autodesk\AutoCAD\$(AcadVersion)\AcDbMgd.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="acmgd"> <HintPath>..\Desktop.References.Autodesk\AutoCAD\$(AcadVersion)\AcMgd.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="AdWindows"> <HintPath>..\Desktop.References.Autodesk\AutoCAD\$(AcadVersion)\AdWindows.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="Autodesk.AutoCAD.Interop"> <HintPath>..\Desktop.References.Autodesk\AutoCAD\$(AcadVersion)\Autodesk.AutoCAD.Interop.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="Autodesk.AutoCAD.Interop.Common"> <HintPath>..\Desktop.References.Autodesk\AutoCAD\$(AcadVersion)\Autodesk.AutoCAD.Interop.Common.dll</HintPath> <Private>False</Private> </Reference> </ItemGroup> </Project>
测试项目配置示例
<PropertyGroup> <UseWindowsForms>true</UseWindowsForms> <UseWPF>true</UseWPF> <Nullable>enable</Nullable> <IsPackable>false</IsPackable> <Configurations>Debug;Release;Staging</Configurations> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <TargetFramework>net8.0-windows</TargetFramework> </PropertyGroup> <ItemGroup> <Compile Remove="obj\**" /> <EmbeddedResource Remove="obj\**" /> <None Remove="obj\**" /> <Page Remove="obj\**" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> <PackageReference Include="Microsoft.TestPlatform" Version="17.10.0" /> <PackageReference Include="Microsoft.TestPlatform.ObjectModel" Version="17.10.0" /> <PackageReference Include="Moq" Version="4.20.70" /> <PackageReference Include="MSTest.TestAdapter" Version="3.3.1" /> <PackageReference Include="MSTest.TestFramework" Version="3.3.1" /> <PackageReference Include="coverlet.collector" Version="6.0.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> <ItemGroup> <None Include="packages.config" /> </ItemGroup>
问题原因分析
- 配置优先级冲突:测试项目自身显式设置了
TargetFramework,与Directory.Build.props中通过Configuration动态切换的全局配置产生冲突,Visual Studio测试资源管理器无法正确解析目标框架,导致测试平台加载失败。 - 输出文件混淆:
AppendTargetFrameworkToOutputPath设为false,导致.NET 4.7和.NET 8的编译输出写入同一目录,测试资源管理器加载时混淆不同框架的依赖文件,引发引用缺失或类型加载错误。 - 测试平台兼容性瑕疵:Visual Studio测试资源管理器对动态切换目标框架的混合.NET项目支持不足,尤其是跨.NET Framework与.NET 8的场景,容易触发底层运行时错误(如
StackOverflowException)。
解决办法
1. 对齐测试项目与全局配置
移除测试项目中显式的TargetFramework配置,让测试项目完全继承Directory.Build.props的动态目标框架设置,同时添加对应配置(如Debug-Framework、Debug-2021等):
<PropertyGroup> <UseWindowsForms>true</UseWindowsForms> <UseWPF>true</UseWPF> <Nullable>enable</Nullable> <IsPackable>false</IsPackable> <Configurations>Debug;Release;Staging;Debug-Framework;Release-Framework;Debug-2021;Debug-2022;Debug-2023;Debug-2024;Debug-2025</Configurations> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <!-- 移除显式TargetFramework,继承全局设置 --> </PropertyGroup>
2. 分离不同框架的输出路径
修改Directory.Build.props,恢复目标框架在输出路径中的区分,避免文件冲突:
<PropertyGroup> <AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath> <!-- 或自定义分离路径 --> <OutputPath>bin\$(Configuration)\$(TargetFramework)</OutputPath> </PropertyGroup>
3. 优化测试依赖包配置
升级测试相关包到最新稳定版本,移除不必要的直接引用(Microsoft.TestPlatform和Microsoft.TestPlatform.ObjectModel会由Microsoft.NET.Test.Sdk自动引入):
<ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" /> <PackageReference Include="Moq" Version="4.20.70" /> <PackageReference Include="MSTest.TestAdapter" Version="3.4.0" /> <PackageReference Include="MSTest.TestFramework" Version="3.4.0" /> <PackageReference Include="coverlet.collector" Version="6.0.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup>
4. 清理缓存并重置测试资源管理器
- 删除解决方案的
bin、obj目录,重新构建项目 - 在Visual Studio中设置测试处理器架构为
x64(匹配Autodesk产品的64位环境):测试 -> 测试设置 -> 默认处理器架构 - 关闭Visual Studio,删除
.vs隐藏目录后重新打开解决方案
内容的提问来源于stack exchange,提问作者Steve_CAD
相关产品推荐
相关产品推荐

