多目标项目禁用CleanSQLiteInteropFiles仍出现SQLite.Interop.dll删除失败
多目标类库TeamCity构建清理阶段偶发SQLite.Interop.dll占用错误
问题背景
- 维护一个多目标类库(目标框架:net472 + netstandard2.0),引用linq2db.SQLite 5.4.1 NuGet包
- 该类库被两个项目引用:net472 WPF应用、net6.0控制台应用
- linq2db.SQLite依赖System.Data.SQLite.Core 1.0.118,后者又依赖Stub.System.Data.SQLite.Core.NetFramework 1.0.118,这个Stub包包含定义了
CleanSQLiteInteropFiles目标的.targets文件 - 本地构建无异常,但TeamCity的构建在清理阶段偶发报错:
\x86\SQLite.Interop.dll和\x64\SQLite.Interop.dll被其他进程占用,错误触发自CleanSQLiteInteropFiles目标执行时 - 已尝试在类库
.csproj中添加以下属性配置,SQLite.Interop.dll已显示为内容文件,但问题仍偶发,且CleanSQLiteInteropFiles目标似乎仍在执行:
<PropertyGroup> <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles> <CopySQLiteInteropFiles>false</CopySQLiteInteropFiles> <CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles> <CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles> </PropertyGroup>
配置失效原因分析
- 属性作用范围未覆盖所有目标框架:多目标项目中,若属性未明确指定作用于所有TargetFramework,可能仅对某个框架生效,导致其他框架的
CleanSQLiteInteropFiles目标仍被触发 - Stub的.targets文件导入顺序问题:如果属性配置在Stub包的
.targets文件导入之前,Stub的配置可能会覆盖你设置的CleanSQLiteInteropFiles=false - 并行构建的进程冲突:TeamCity默认可能启用MSBuild并行构建,多目标项目的不同框架清理任务同时执行,导致文件被交叉占用
解决方案
1. 确保属性对所有目标框架生效
将属性配置修改为针对所有TargetFramework生效,或者为每个框架单独配置:
<!-- 全局生效,覆盖所有目标框架 --> <PropertyGroup Condition=" '$(TargetFramework)' != '' "> <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles> <CopySQLiteInteropFiles>false</CopySQLiteInteropFiles> <CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles> <CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles> </PropertyGroup>
2. 显式移除CleanSQLiteInteropFiles目标的依赖
如果属性设置仍被覆盖,直接从Clean目标的依赖列表中移除CleanSQLiteInteropFiles:
<Target Name="OverrideSQLiteCleanTarget" BeforeTargets="Clean"> <!-- 从CleanDependsOn中移除CleanSQLiteInteropFiles目标 --> <PropertyGroup> <CleanDependsOn>$(CleanDependsOn.Replace('CleanSQLiteInteropFiles', ''))</CleanDependsOn> </PropertyGroup> </Target>
3. 禁用TeamCity的并行构建
在TeamCity的MSBuild构建步骤中,添加参数/m:1(禁用并行),或者降低并行度,避免多目标框架的清理任务同时执行:
msbuild YourSolution.sln /m:1 /t:Clean;Build
4. 检查.targets导入顺序
确认你的属性配置放在<Import Project="Sdk.props" />之后,且在NuGet包的.targets导入之前(通常NuGet的导入会自动放在项目文件末尾,但可以手动调整),确保你的属性能覆盖Stub包的默认配置。
内容的提问来源于stack exchange,提问作者bairog
相关产品推荐
相关产品推荐

