Visual Studio 2010无法加载一个导入了<ProjectConfiguration>元素的项目

4
我们有一个大型系统(约800个项目),正在从旧的构建系统迁移到Visual Studio 2010。在过去几周中,我们已经手动为每个项目创建了Visual Studio项目文件(.vcxproj格式),并且能够使用仅MSBuild.exe(WIN!)从命令行构建整个系统。由于需要转换的项目数量很大,手动创建项目文件比使用VS项目向导创建更有效,因为我们以前的构建系统未使用Visual Studio项目文件。
为了维护和遵循DRY原则,我们将大部分构建配置(编译器/链接器开关、包含路径等)重构为常见的.targets和.props文件。由于每个项目的配置集相同,我们还将包含项的放入常见的.props文件中,并且一切都适用于我们的无人值守夜间构建。
很遗憾,Visual Studio 2010 IDE(RTM版本)无法加载这些项目。当我尝试加载该项目时,会出现错误提示“项目[Foo]不包含任何配置”。如果我手动从我们的.props文件中复制到任何一个项目中,则IDE可以加载该项目。
在搜索过程中,我发现MS Connect上的this问题,但它被标记为“关闭为外部”,MS回复称正在调查此问题,以在下一个公共版的Visual Studio中解决。手动向大约800个项目添加完全相同的元素不是可接受的解决办法。由于项目可以在VS之外构建并且运行正常,因此我必须假设问题在于Visual Studio解析/加载项目文件的方式。
有人能否找到解决此问题的解决方法?是否有关于何时/是否将在Visual Studio中修复此问题的信息?
3个回答

3

我已经为这个问题创建了一个解决方法。这只适用于VS2010,而不是之前的版本,因为它需要MSBuild 4。

首先,创建一个名为Configure.xslt的文件,并添加以下内容。

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msbuild="http://schemas.microsoft.com/developer/msbuild/2003">
  <xsl:output version="1.0" encoding="UTF-8" indent="yes" />
  <xsl:template match="/msbuild:Project">
    <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="*">
    <xsl:copy-of select="." />
  </xsl:template>
  <xsl:template match="msbuild:ItemGroup[@Label = 'ProjectConfigurations']">
    <xsl:copy-of select="document('Default.props')/msbuild:Project/msbuild:ItemGroup[@Label = 'ProjectConfigurations']" />
  </xsl:template>
</xsl:transform>

现在,创建一个名为Default.props的文件,并添加以下内容。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" InitialTargets="Configure" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- This must come first, or else VS IDE's property sheets will choke. -->
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

  <!-- The following configurations will be pasted into the importing project file on demand. -->
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>

  <!-- XLST task which manipulates the project file and performs an in-place replacement. -->
  <Target Name="Configure" Condition="Exists('$(MSBuildThisFileDirectory)Configure.xslt')" Inputs="$(MSBuildProjectFile);$(MSBuildThisFileFullPath);$(MSBuildThisFileDirectory)Configure.xslt" Outputs="$(MSBuildProjectFile);$(OutDir)">
    <Message Text="Configuring $(MSBuildProjectFile)..." />
    <XslTransformation XslInputPath="$(MSBuildThisFileDirectory)Configure.xslt" XmlInputPaths="$(MSBuildProjectFile)" OutputPaths="$(MSBuildProjectFile).tmp" />
    <Move SourceFiles="$(MSBuildProjectFile).tmp" DestinationFiles="$(MSBuildProjectFile)" />
    <MakeDir Directories="$(OutDir)" />
  </Target>

  <!-- The remaining MSBuild imports. -->
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

这个文件是您项目的“属性表”,包括配置等所有公共属性。请根据需要自定义它。重要部分是 <Target> 节点(创建名为 Configure 的新目标)和 <Project> 节点中的 InitialTargets 属性(告诉 MSBuild 最初执行 Configure 目标)。
之后,将 Configure.xsltDefault.props 移动到您选择的目录中。
最后,在所有项目中使用以下模板。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Change the directory below according to the path containing the above files. -->
  <Import Project="Directory\Default.props" />
  <!-- The ItemGroup below will be effectively replaced by the same ItemGroup inside Default.props. -->
  <ItemGroup Label="ProjectConfigurations" />
</Project>

从VS提示符中,运行一个初始的msbuild来填充你的文件配置,否则VS IDE将无法打开你的项目(因为同样的缺陷促使了这个解决方法)。或者,你的模板可能包含任何虚假配置,只是为了让IDE最初能够打开项目--效果是相同的。
已知注意事项:你不能使用IDE创建每个项目的配置(因为IDE会强制将任何找到的配置分组在ProjectConfigurations标签下)。你可以直接在项目文件的XML数据中创建它们,并且只要你不将它们标记为ProjectConfigurations,它们就不会被替换或删除。

1

在VS2012上是可能的,但您必须记住导入/初始化变量的顺序非常重要。

您需要将 非常早地放在项目文件中,实际上是第一项。我认为配置可能需要系统.props文件才能正常工作,这就是为什么您会收到该错误消息。在我修改了我的VS proj之前,我也遇到了与您相同的错误。


0

在这个问题中得到了答案:是否可能使用MSBuild将配置定义移动到属性表中?

这里是连接问题,说明这没有进入RTM:https://connect.microsoft.com/VisualStudio/feedback/details/514008/vcxproj-doesnt-examine-imports-to-find-project-configurations-beta-2

我没有找到其他解决方法,除了生成项目。一个技巧是在项目文件中放置一个标志值,比如${CommonConfigurations},然后只需使用字符串属性函数替换它,生成完全新的项目文件供VS解决方案使用。在这种情况下,我也会生成解决方案文件,这样您就不必在两个地方维护项目列表。


抱歉重发了。根据我所找到的信息,这个更改也没有出现在SP1中(我还没有安装SP1,所以无法确认或否认)。 - Dylan Bourque
进一步阐述一下,就像我说的那样,我们已经能够使用导入文件中的<ProjectConfiguration>项使用MSBuild构建我们的系统。我希望有人找到了一种方法来在VS IDE中加载项目。由于我们正在赶时间,我正在编写批处理脚本和XSLT来将<ItemGroup>添加到678个.vcxproj项目中。 - Dylan Bourque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接