msbuild导入和覆盖文件

时间:2014-01-22 15:14:49

标签: c# vb.net visual-studio inheritance msbuild

我有两个项目和一个解决方案文件:

c:\dev\base\proja\proja.vbproj
c:\dev\base\proja\myfile1.aspx
c:\dev\base\proja\myfile1.aspx.vb
c:\dev\base\proja\myfile1.aspx.vb.designer
c:\dev\base\proja\myfile2.aspx
c:\dev\base\proja\myfile2.aspx.vb
c:\dev\base\proja\myfile2.aspx.vb.designer

c:\dev\base\projb\mysln.sln
c:\dev\base\projb\projb.vbproj
c:\dev\base\projb\myfile2.aspx
c:\dev\base\projb\myfile2.aspx.vb
c:\dev\base\projb\myfile2.aspx.vb.designer

proja.vbproj是基础项目,而projb.vbproj旨在导入proja.vbproj并覆盖myfile2.aspx etc个文件。

proja.vbproj看起来像这样:

[...]
<Compile Include="myfile1.aspx.vb">
  <SubType>ASPXCodebehind</SubType>
  <DependentUpon>myfile1.aspx</DependentUpon>
</Compile>
<Compile Include="myfile2.aspx.vb">
  <SubType>ASPXCodebehind</SubType>
  <DependentUpon>myfile2.aspx</DependentUpon>
</Compile>
[...]
<Content Include="myfile1.aspx" />
<Content Include="myfile2.aspx" />
[...]

projb.vbproj看起来像这样:

[...]
<Import Project="$(ProjectDir)..\proja\proja.vbproj" />
[...]
<Compile Include="myfile2.aspx.vb">
  <SubType>ASPXCodebehind</SubType>
  <DependentUpon>myfile2.aspx</DependentUpon>
</Compile>
[...]
<Content Include="myfile2.aspx" />
[...]

projb.vbproj旨在覆盖proja.vbproj的自定义文件 - 提供维护项目的单个规范化位置,同时允许针对每个站点的自定义进行特定覆盖。

当我在Visual Studio 2013中加载projb.vbproj并尝试构建它时,会出现问题。它会引发大量错误,因为它无法解析位于myfile1.aspxproja.vbproj和相关文件的位置。这似乎是因为导入的路径是相对于projb.vbproj位置而不是proja.vbproj文件位置。

我已尝试将$(MSBuildProjectDirectory)预先附加到proja.vbproj中的所有文件 - 但这并不能解决问题,因为我认为$(MSBuildProjectDirectory)是根据项目的上下文设置的正在被开放而不是进口。

我不想将整个myproja.vbproj文件内容复制到myprojb.vbproj只是为了覆盖一个文件 - 这看起来很混乱,并且反对看似以继承为中心的msbuild方法,但也许我是这里错了......

有没有办法完成我追求的目标?那是;使用另一个项目的文件位置覆盖某个项目的某些文件位置,而不必复制整个项目文件?

1 个答案:

答案 0 :(得分:1)

您尝试重复使用项目的某些部分是一件好事,但是您采用的方式有一些缺点(如果您的项目增长,它们只会变得更大):

  • ,因为您发现它无法正常工作
  • 您可以使用$(MsBuildThisFileDirectory)解决此问题,但这意味着无论何时Visual Studio将文件添加到项目中,您都必须再次应用此修复程序
  • 项目b直接依赖于项目a中的所有内容,这种紧密耦合永远不是一个好兆头
  • 如果MsBuild看到Compile Include=aaa,则 aaa添加到编译列表中。即使它已经存在了。所以你没有在这里覆盖任何东西,你只是添加到项目a中包含的文件。不确定这是不是你想要的?

你能做什么呢?

  • 如果项目需要相同的构建设置(对于编译器/链接器/ ...),请将这些设置添加到公共的单独文件中,并将其包含在两个项目中
  • 如果项目需要通用功能,则只将该功能放在项目中,并在其他项目中引用该项目。因此,不要试图用你的构建系统覆盖一些东西,这是一个混乱,提供一个共同的基础,然后添加类。 (我对aspx / bb.net一无所知,但肯定有办法创建你可以在其他人中引用的'库'类型的项目吗?)
  • 回复您的评论:如果只有几个文件不同,您还可以使用一个具有多个构建配置的项目。然后每个构建配置启用不同的文件。所以通常你有Debug和Release这样的配置,现在你重命名这些和额外的配置,比如ReleaseCustom1 / ReleaseCustom2。

例如:

 <!-- 500+ Common Files -->
 <Compile Include="myfile1.aspx.vb"/>
 <Compile Include="myfile2.aspx.vb"/>
 <!-- Some Specific Files -->
 <Compile Include="customfile1.aspx" Condition="'$(Configuration)'=='ReleaseCustom1'"/>
 <Compile Include="customfile2.aspx" Condition="'$(Configuration)'=='ReleaseCustom2'"/>