Visual Studio 2010 cannot load a project into which <ProjectConfiguration> elements are imported

We have a large (~ 800 separate projects) system that we are moving from the old build system to Visual Studio 2010. Over the past few weeks, we have manually created Visual Studio project files (format .vcxproj) for each project, and we can build the whole system from the command line using only MSBuild.exe (WIN !!). Due to the large number of projects that needed to be converted, it was more efficient to create project files manually than to create them using the VS project wizard, since our previous build system did not use Visual Studio project files.

For servicing and binding to DRY, we have most of the assembly configuration (compiler / linker switches, including paths, etc.) reorganized into common .targets and .props files. Since the configuration set for each project is the same, we also put a <ItemGroup> containing <ProjectConfiguration> elements in a common .props file, and everything works fine for our automatic nightly build.

Unfortunately, the Visual Studio 2010 IDE (RTM version) cannot load these projects. When I try to download a project, I get an error: "Project [Foo] does not contain any configurations." If I manually <ItemGroup> from our .props file to any of the projects, the IDE can load the project.

During the search, I found this problem in MS Connect, but it is marked as "Closed as external" with a response from MS that the problem is being investigated for the next public release of Visual Studio. Manually adding an element of exactly the same <ItemGroup> to ~ 800 projects is not an acceptable solution. Since projects are built outside of VS and work fine, I have to assume that the problem is that Visual Studio is parsing / loading the project files.

Has anyone been able to find a workaround for this problem? Does anyone have information on when / if this will be fixed in Visual Studio?

+4
source share
3 answers

I created a workaround for this problem. This only works on VS2010 and not on previous versions, as this requires MSBuild 4.

First create a file called Configure.xslt with the following contents.

 <?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> 

Now create a file called Default.props with the following contents.

 <?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 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> 

This file is your separate β€œproperty sheet” containing all the common properties for your projects, including configurations. Customize it to your needs. Important parts are the <Target> node (which creates a new target called Configure ) and the InitialTargets attribute in the <Project> node (which tells MSBuild to start the Configure destination).

After that, move both Configure.xslt and Default.props to the directory of your choice.

Finally, use the following template in all of your projects.

 <?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> 

On the VS command line, run the initial msbuild to populate the file using the configurations, otherwise the VS IDE will not open your project (due to the same error that motivated this workaround in the first place). Alternatively, your template may contain any dummy configuration, only to allow the IDE to open the project from the beginning - the effect is the same.

Known caveats: You cannot create configurations for each project using the IDE (because the IDE will force any configurations found under the ProjectConfigurations label). You can create them directly in the project data files, and as soon as you name them ProjectConfigurations , they will not be replaced or deleted.

+3
source

This is possible on VS2012, however you must remember that the order in which you import / initialize the variables is very important.

You will need to be very early in the project file, the first element is valid. I think that for the correct operation of the .props system files, configuration may be required, and that is why you get this error. I had the same error as you had on VS2012, until I hacked into a VS project.

+1
source

Answer to this question: Is it possible to move configuration definitions to the property sheet using MSBuild?

Here is the connectivity issue stating that this did not affect RTM: https://connect.microsoft.com/VisualStudio/feedback/details/514008/vcxproj-doesnt-examine-imports-to-find-project-configurations-beta -2

I did not find a workaround other than creating projects. One trick is to put the sentinal value in the project file, for example $ {CommonConfigurations}, and simply use the string properties function to replace it, generating completely new project files for use in the VS solution. I will also generate a solution file in this case, so you do not need to maintain a list of projects in two places.

0
source

Source: https://habr.com/ru/post/1347261/


All Articles