如何阻止Visual Studio构建时覆盖Xamarin Android项目文件?
问题根源
你的问题出在Visual Studio的Xamarin Android项目系统会自动扫描Resources和Assets目录,自动生成无条件的<ItemGroup>和默认<PropertyGroup>,这些自动生成的配置会覆盖你手动定义的条件化配置,导致不同客户端的资源被混在一起打包。
解决方案
1. 禁用自动资源扫描
在项目文件的全局<PropertyGroup>(所有条件配置之外的位置)添加以下配置,阻止VS自动扫描并添加资源:
<PropertyGroup> <!-- 禁用VS自动生成资源条目 --> <AndroidUseManagedDesignTimeResourceGenerator>False</AndroidUseManagedDesignTimeResourceGenerator> <!-- 禁用自动生成默认的Resource.designer.cs路径 --> <AndroidGenerateResourceDesigner>False</AndroidGenerateResourceDesigner> </PropertyGroup>
2. 清理自动生成的冗余配置
删除项目文件中所有无Condition的<ItemGroup>(即混合包含Resources\ClientTwo和Resources\Base资源的条目),以及无Condition的<PropertyGroup>里的AndroidResgenFile、MonoAndroidResourcePrefix等属性,这些都是VS自动添加的干扰项。
3. 严格隔离各客户端的资源
为每个客户端的配置添加资源排除/包含规则,确保只加载当前客户端的资源:
Base客户端(Debug/Release配置)
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <AndroidResgenFile>Resources\Base\Resource.designer.cs</AndroidResgenFile> <AndroidResgenClass>Resource</AndroidResgenClass> <MonoAndroidResourcePrefix>Resources\Base</MonoAndroidResourcePrefix> <AndroidResgenOutput>$(AndroidResgenFile)</AndroidResgenOutput> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <AndroidResgenFile>Resources\Base\Resource.designer.cs</AndroidResgenFile> <AndroidResgenClass>Resource</AndroidResgenClass> <MonoAndroidResourcePrefix>Resources\Base</MonoAndroidResourcePrefix> <AndroidResgenOutput>$(AndroidResgenFile)</AndroidResgenOutput> </PropertyGroup> <ItemGroup Condition="'$(Configuration)' == 'Debug' Or '$(Configuration)' == 'Release'"> <!-- 排除其他客户端的所有资源 --> <AndroidResource Remove="Resources\ClientTwo\**" /> <AndroidAsset Remove="Assets\ClientTwo\**" /> <!-- 包含Base客户端的所有资源 --> <AndroidResource Include="Resources\Base\**" /> <AndroidAsset Include="Assets\Base\**" /> <!-- 单独设置需要生成器的资源 --> <AndroidResource Include="Resources\Base\drawable\logo.png"> <Generator>MSBuild:UpdateGeneratedFiles</Generator> <SubType>Designer</SubType> </AndroidResource> </ItemGroup>
ClientTwo客户端(ClientTwoDebug/ClientTwoRelease配置)
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ClientTwoDebug|AnyCPU' "> <AndroidResgenFile>Resources\ClientTwo\Resource.designer.cs</AndroidResgenFile> <AndroidResgenClass>Resource</AndroidResgenClass> <MonoAndroidResourcePrefix>Resources\ClientTwo</MonoAndroidResourcePrefix> <AndroidResgenOutput>$(AndroidResgenFile)</AndroidResgenOutput> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ClientTwoRelease|AnyCPU' "> <AndroidResgenFile>Resources\ClientTwo\Resource.designer.cs</AndroidResgenFile> <AndroidResgenClass>Resource</AndroidResgenClass> <MonoAndroidResourcePrefix>Resources\ClientTwo</MonoAndroidResourcePrefix> <AndroidResgenOutput>$(AndroidResgenFile)</AndroidResgenOutput> </PropertyGroup> <ItemGroup Condition="'$(Configuration)' == 'ClientTwoDebug' Or '$(Configuration)' == 'ClientTwoRelease'"> <!-- 排除Base客户端的所有资源 --> <AndroidResource Remove="Resources\Base\**" /> <AndroidAsset Remove="Assets\Base\**" /> <!-- 包含ClientTwo客户端的所有资源 --> <AndroidResource Include="Resources\ClientTwo\**" /> <AndroidAsset Include="Assets\ClientTwo\**" /> <!-- 单独设置需要生成器的资源 --> <AndroidResource Include="Resources\ClientTwo\drawable\logo.png"> <Generator>MSBuild:UpdateGeneratedFiles</Generator> <SubType>Designer</SubType> </AndroidResource> </ItemGroup>
4. 处理Resource.designer.cs的编译冲突
每个客户端的Resource.designer.cs在不同目录,需要在项目文件中为它们添加条件包含,确保只有当前配置对应的文件被编译:
<Compile Include="Resources\Base\Resource.designer.cs" Condition="'$(Configuration)' == 'Debug' Or '$(Configuration)' == 'Release'" /> <Compile Include="Resources\ClientTwo\Resource.designer.cs" Condition="'$(Configuration)' == 'ClientTwoDebug' Or '$(Configuration)' == 'ClientTwoRelease'" />
注意事项
- 不要在VS解决方案资源管理器中手动添加资源文件,否则会再次生成无条件的
<ItemGroup>,破坏隔离规则。 - 每次修改配置后,执行清理解决方案再构建,避免缓存的旧资源干扰。
- 确保各客户端的资源目录结构完全一致(比如都有
drawable、values子目录),这样生成的Resource类结构统一,业务代码无需修改。
内容的提问来源于stack exchange,提问作者Cody
相关产品推荐
相关产品推荐

