MSBuild - Circular dependency in the target dependency graph - tfs

I am getting the following error in my build
Error MSB4006: There is a circular dependency in the target dependency graph involving target "DoPublish".
The DoPublish is triggering Publish and I assume the Build. How can I avoid this.
I am using the Visual Studio build. I was using the MSBUILD with the targets /t:UpdateVersion;DoPublish;publish, which worked. I would like to use the Visual Studio build in TFS instead of MSBUILD
Project:
<Target Name="UpdateVersion" AfterTargets="PostBuildEvent">
<RevisionTask>
<Output TaskParameter="PublishVersion" PropertyName="PublishVersion" />
</RevisionTask>
<Message Text="The Version is $(PublishVersion)" Importance="high" />
<PropertyGroup>
<ApplicationVersion>$(PublishVersion)</ApplicationVersion>
</PropertyGroup>
<ItemGroup>
<ConfigFile Include="$(MSBuildProjectDirectory)\Configs\$(Configuration)\AppDeploy.config" />
</ItemGroup>
<Copy SourceFiles="#(ConfigFile)" DestinationFolder="$(TargetDir)" Condition=" '$(Configuration)' == 'DEV' OR '$(Configuration)' == 'SIT' OR '$(Configuration)' == 'UAT' " ContinueOnError="true" />
<Copy SourceFiles="#(ConfigFile)" DestinationFolder="$(MSBuildProjectDirectory)" Condition=" '$(Configuration)' == 'DEV' OR '$(Configuration)' == 'SIT' OR '$(Configuration)' == 'UAT' " ContinueOnError="true" />
<Message Text="Copying File from $(MSBuildProjectDirectory)\Configs\$(Configuration)\Web.config to $(TargetDir)" Importance="high" />
</Target>
<Target Name="DoPublish" AfterTargets="UpdateVersion" Condition=" '$(BuildingInsideVisualStudio)' != '' ">
<MSBuild Projects="$(ProjectFileName)" Targets="Publish" Properties="ApplicationVersion=$(PublishVersion)" />
<!-- Write publish.htm file for ClickOnce -->
<Message Text="FileUpdate - $(ProjectDir)\Configs\publish.htm: Replace {PublishVersion} with $(PublishVersion)" Importance="high" />
<FileUpdate Files="$(ProjectDir)\Configs\publish.htm" IgnoreCase="true" Multiline="true" Singleline="false" Regex="{PublishVersion}" ReplacementText="$(PublishVersion)" />
<Message Text="FileUpdate - $(ProjectDir)\Configs\publish.htm: Replace {AssemblyName} with $(AssemblyName)" Importance="high" />
<FileUpdate Files="$(ProjectDir)\Configs\publish.htm" IgnoreCase="true" Multiline="true" Singleline="false" Regex="{AssemblyName}" ReplacementText="$(AssemblyName)" />
<Message Text="FileUpdate - $(ProjectDir)\Configs\publish.htm: Replace {ProductName} with $(ProductName)" Importance="high" />
<FileUpdate Files="$(ProjectDir)\Configs\publish.htm" IgnoreCase="true" Multiline="true" Singleline="false" Regex="{ProductName}" ReplacementText="$(ProductName)" />
<Copy SourceFiles="$(ProjectDir)\Configs\publish.htm" DestinationFiles="$(PublishDir)publish.htm" />
</Target>

I created a web app project and tested this on my environment (TFS2015) with following of your code kept:
<Target Name="UpdateVersion" AfterTargets="PostBuildEvent">
<Message Text="The Version is $(PublishVersion)" Importance="high" />
<PropertyGroup>
<ApplicationVersion>$(PublishVersion)</ApplicationVersion>
</PropertyGroup>
<Message Text="Copying File from $(MSBuildProjectDirectory)\Configs\$(Configuration)\Web.config to $(TargetDir)" Importance="high" />
</Target>
<Target Name="DoPublish" AfterTargets="UpdateVersion" Condition="'$(BuildingInsideVisualStudio)' != 'true'">
<MSBuild Projects="$(ProjectFileName)" Targets="Publish" />
</Target>
But I couldn't reproduce this issue. The build can be completed successfully. I can only see MSB4006 error when "Target="Publish" isn't added in "DoPublish" target.
I changed Condition=" '$(BuildingInsideVisualStudio)' != '' " to Condition="'$(BuildingInsideVisualStudio)' != 'true'" as the BuildingInsideVisualStudio value is always empty under my environment. "DoPublish" target does not run with Condition=" '$(BuildingInsideVisualStudio)' != '' ".
Since I cannot add comment, I have a question need to check here: What do you mean by using the Visual Studio build in TFS instead of MSBUILD?

After seeing this post I came up with similar solution overriding the AfterPubish target.
To correct the circular dependency, just change the target name to AfterPublish and removed the AfterTargerts attribute.
<Target Name="AfterPublish" Condition=" '$(BuildingInsideVisualStudio)' != '' ">
<MSBuild Projects="$(ProjectFileName)" Targets="Publish" Properties="ApplicationVersion=$(PublishVersion)" />
<!-- Write publish.htm file for ClickOnce -->
<Message Text="FileUpdate - $(ProjectDir)\Configs\publish.htm: Replace {PublishVersion} with $(PublishVersion)" Importance="high" />
<FileUpdate Files="$(ProjectDir)\Configs\publish.htm" IgnoreCase="true" Multiline="true" Singleline="false" Regex="{PublishVersion}" ReplacementText="$(PublishVersion)" />
<Message Text="FileUpdate - $(ProjectDir)\Configs\publish.htm: Replace {AssemblyName} with $(AssemblyName)" Importance="high" />
<FileUpdate Files="$(ProjectDir)\Configs\publish.htm" IgnoreCase="true" Multiline="true" Singleline="false" Regex="{AssemblyName}" ReplacementText="$(AssemblyName)" />
<Message Text="FileUpdate - $(ProjectDir)\Configs\publish.htm: Replace {ProductName} with $(ProductName)" Importance="high" />
<FileUpdate Files="$(ProjectDir)\Configs\publish.htm" IgnoreCase="true" Multiline="true" Singleline="false" Regex="{ProductName}" ReplacementText="$(ProductName)" />
<Copy SourceFiles="$(ProjectDir)\Configs\publish.htm" DestinationFiles="$(PublishDir)publish.htm" />
</Target>

Related

Build project with multiple targetframeworks in TFS as a NuGet package

I want to build my NuGet package in one of my TFS build steps.
Because .NET Standard 2.0 is currently not supported by the TFS NuGet step, I am using /t:pack as the build argument in my MSBuild invocation.
When I only use one TargetFramework it is working fine. My assemblies get a version and my NuGet package too.
Even if I am using an AssemblyInfo.cs in .NET Standard 2.0 - explained in this answer.
So far no problem, but if I want to build now on two different TargetFrameworks like <TargetFramework>netstandard2.0;net45</TargetFramework> my NuGet package won't get a Version.
So in the end this is working and is generating a versioned NuGet file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateNuspecDependsOn>$(GenerateNuspecDependsOn);ReadPackageVersionFromOutputAssembly</GenerateNuspecDependsOn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<Target Name="ReadPackageVersionFromOutputAssembly" DependsOnTargets="Build">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="PackAssembly" />
</GetAssemblyIdentity>
<PropertyGroup>
<PackageVersion>%(PackAssembly.Version)</PackageVersion>
</PropertyGroup>
</Target>
<ItemGroup>
<Compile Remove="AccessControl\**" />
<EmbeddedResource Remove="AccessControl\**" />
<None Remove="AccessControl\**" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\common\Version.cs" Link="Properties\Version.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.8.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="MyEngine">
<HintPath>..\libs\NetStandard\MyEngine.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>
So here is my current .csproj file. This builds too and also generates a NuGet file. But in this case my NuGet file is unversioned. Why is it this way and how can I fix it?
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateNuspecDependsOn>$(GenerateNuspecDependsOn);ReadPackageVersionFromOutputAssembly</GenerateNuspecDependsOn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<Target Name="ReadPackageVersionFromOutputAssembly" DependsOnTargets="Build">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="PackAssembly" />
</GetAssemblyIdentity>
<PropertyGroup>
<PackageVersion>%(PackAssembly.Version)</PackageVersion>
</PropertyGroup>
</Target>
<ItemGroup>
<Compile Remove="AccessControl\**" />
<EmbeddedResource Remove="AccessControl\**" />
<None Remove="AccessControl\**" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\common\Version.cs" Link="Properties\Version.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.8.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<Reference Include="MyEngine">
<HintPath>..\libs\NetStandard\MyEngine.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="MyEngine">
<HintPath>..\libs\NET45\MyEngine.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>
The targets can be adapted to support multi-targeting like this:
<Target Name="ReadPackageVersionFromOutputAssemblySingleTfm" Returns="#(PackAssembly)" Condition="'$(IsCrossTargetingBuild)' != 'true'">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="PackAssembly" />
</GetAssemblyIdentity>
<PropertyGroup>
<PackageVersion>%(PackAssembly.Version)</PackageVersion>
</PropertyGroup>
</Target>
<Target Name="ReadPackageVersionFromOutputAssemblyMultipleTfms" Condition="'$(IsCrossTargetingBuild)' == 'true'">
<PropertyGroup>
<FirstTargetFramework>$([System.String]::Copy($(TargetFrameworks)).Split(';').GetValue(0))</FirstTargetFramework>
</PropertyGroup>
<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="ReadPackageVersionFromOutputAssemblySingleTfm" Properties="TargetFramework=$(FirstTargetFramework)">
<Output TaskParameter="TargetOutputs" ItemName="PackAssembly" />
</MSBuild>
<PropertyGroup>
<PackageVersion>%(PackAssembly.Version)</PackageVersion>
</PropertyGroup>
</Target>
<Target Name="ReadPackageVersionFromOutputAssembly" DependsOnTargets="Build;ReadPackageVersionFromOutputAssemblySingleTfm;ReadPackageVersionFromOutputAssemblyMultipleTfms" />

MSBuild: how to use the nested properties like in Ant

I have batch of properties in my MSBuild configuration file
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<USERNAME1_DropboxPublic>e:\path\to\Dropbox\for\first\user</USERNAME1_DropboxPublic>
<USERNAME2_DropboxPublic>e:\path\to\Dropbox\for\second\user</USERNAME2_DropboxPublic>
<USERNAME3_DropboxPublic>e:\path\to\Dropbox\for\third\user</USERNAME3_DropboxPublic>
</PropertyGroup>
....
</Project>
And I want to get property depends on current the username.
Also I know that ant solves this problem by using nested properties like this ${${user.name}_DropboxPublic}
How can I solve this problem with MSBuild tool?
Here are some of the "tricks".
Save the below xml into a file called "MSBuild_Conditionals.xml"
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapper">
<!-- -->
<PropertyGroup>
<MyFavoriteFoodComplement Condition="'$(FavoriteFood)'=='PeanutButter'">Jelly</MyFavoriteFoodComplement>
<MyFavoriteFoodComplement Condition="'$(FavoriteFood)'=='Steak'">Potatoes</MyFavoriteFoodComplement>
<!-- Check to see if a match was given (by seeing if the variable value is an empty string), if no match (aka, an empty string), do a default -->
<MyFavoriteFoodComplement Condition="'$(MyFavoriteFoodComplement)'==''">CookiesTheDefaultFavoriteFoodComplement</MyFavoriteFoodComplement>
</PropertyGroup>
<Choose>
<When Condition=" '$(Configuration)'=='Debug' ">
<PropertyGroup>
<MyChooseVariable001>DebugSuffix001</MyChooseVariable001>
<MyChooseVariable002>DebugSuffix002</MyChooseVariable002>
<MyChooseVariable003>DebugSuffix003</MyChooseVariable003>
</PropertyGroup>
</When>
<When Condition=" '$(Configuration)'=='Release' ">
<PropertyGroup>
<MyChooseVariable001>ReleaseSuffix001</MyChooseVariable001>
<MyChooseVariable002>ReleaseSuffix002</MyChooseVariable002>
<MyChooseVariable003>ReleaseSuffix003</MyChooseVariable003>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<MyChooseVariable001>DefaultValue001</MyChooseVariable001>
<MyChooseVariable002>DefaultValue002</MyChooseVariable002>
<MyChooseVariable003>DefaultValue003</MyChooseVariable003>
</PropertyGroup>
</Otherwise>
</Choose>
<!-- -->
<Target Name="TestCreateProperty">
<CreateProperty Value="Here is a created property using another property : $(MyFavoriteFoodComplement)">
<Output TaskParameter="Value" PropertyName="MyCreateProperty" />
</CreateProperty>
<Message Text=" MyCreateProperty = $(MyCreateProperty)" />
<Message Text=" " />
<CreateProperty Condition="'$(FavoriteFood)'=='PeanutButterX'" Value="Conditional Create Property : $(MyFavoriteFoodComplement)">
<Output TaskParameter="Value" PropertyName="MyCreatePropertyWithCondition" />
</CreateProperty>
<CreateProperty Condition="'$(MyCreatePropertyWithCondition)'==''" Value="Conditional Create Property : DEFAULT">
<Output TaskParameter="Value" PropertyName="MyCreatePropertyWithCondition" />
</CreateProperty>
<Message Text=" MyCreatePropertyWithCondition = $(MyCreatePropertyWithCondition)" />
</Target>
<!-- -->
<Target Name="ShowVariables">
<Message Text="Configuration = $(Configuration)" />
<Message Text="FavoriteFood = $(FavoriteFood)" />
<Message Text=" " />
<Message Text="MyFavoriteFoodComplement = $(MyFavoriteFoodComplement)" />
<Message Text="MyChooseVariable001 = $(MyChooseVariable001)" />
<Message Text="MyChooseVariable002 = $(MyChooseVariable002)" />
<Message Text="MyChooseVariable003 = $(MyChooseVariable003)" />
</Target>
<!-- -->
<!-- -->
<!-- -->
<Target Name="AllTargetsWrapper">
<!-- -->
<CallTarget Targets="ShowVariables" />
<!-- -->
<CallTarget Targets="TestCreateProperty" />
<!-- -->
</Target>
<!-- -->
</Project>
Save this into a .bat file.
set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v3.5
call %msBuildDir%\msbuild.exe MSBuild_Conditionals.xml /p:Configuration=Release;FavoriteFood=PeanutButter /l:FileLogger,Microsoft.Build.Engine;logfile=MSBuild_Conditionals_LOG.log
set msBuildDir=
Output (with the parameters in the .bat file above)
Build started 6/01/2013 11:33:33 PM.
__________________________________________________
Project ".\MSBuild_Conditionals.xml" (default targets):
Target AllTargetsWrapper:
Target ShowVariables:
Configuration = Release
FavoriteFood = PeanutButter
MyFavoriteFoodComplement = Jelly
MyChooseVariable001 = ReleaseSuffix001
MyChooseVariable002 = ReleaseSuffix002
MyChooseVariable003 = ReleaseSuffix003
Target TestCreateProperty:
MyCreateProperty = Here is a created property using another property : Jelly
MyCreatePropertyWithCondition = Conditional Create Property : DEFAULT
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.01

Error deploying asp.net mvc 3 projects to Windows Azure web site

I have an asp.net mvc 3 project and a separate BusinessLayer project included in the solution. When I'm trying to deploy my site to Azure via local git repository, I'm getting the following error: '<remote_path>\BusinessLayer\BusinessLayer.csproj' is not a deployable project.. No other information is provided in logs. Site perfectly deploys on my local server. So I want to know at least some possible reasons why this error occurs. Thanks in advance.
Here's my .csproj file, if necessary:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{31F2F6FE-10D8-4510-AC61-CBE1962D3940}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BusinessLayer</RootNamespace>
<AssemblyName>BusinessLayer</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="MongoDB.Bson">
<HintPath>..\..\Libs\MongoDB.Bson.dll</HintPath>
</Reference>
<Reference Include="MongoDB.Driver">
<HintPath>..\..\Libs\MongoDB.Driver.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Battle.cs" />
<Compile Include="BattleManager.cs" />
<Compile Include="BattlePlace.cs" />
<Compile Include="Helpers\ConvertHelper.cs" />
<Compile Include="Helpers\ImageHelper.cs" />
<Compile Include="Message.cs" />
<Compile Include="Picture.cs" />
<Compile Include="Place.cs" />
<Compile Include="PlaceManager.cs" />
<Compile Include="Subject.cs" />
<Compile Include="User.cs" />
<Compile Include="Helpers\DBHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
You may need to tell Azure exactly which project it should deploy, which you can do using a .deployment file at the root of your project. e.g.
[config]
project = WebProject/WebProject.csproj
Please see this page for more information about this.
Sounds like you're trying to deploy the BusinessLayer project and not the Website project. As long as your MVC site project has a reference to BusinessLayer, just deploy the website. BusinessLayer will be included as a reference.
You can't deploy BusinessLayer by itself, as it is a library and not an application.

Replace values in xml using ANT

I want to replace the ProductVersion value at <DefineConstants> node of the following xml. Remaining part of the line has to be preserved.
Example:
<DefineConstants>XXXXX;ProductVersion=20.323.23;YYYYY</DefineConstants>
to
<DefineConstants>XXXXX;ProductVersion=21.58.44;YYYYY</DefineConstants>
I tried the replaceregexp but it changes the remaining contents.
<replaceregexp file="${basedir}\Installer.wixproj"
match="ProductVersion=([0-9].*);(.*)"
replace="ProductVersion=${SpaceVersion};\1"
byline="true"
/>
Could you guide me what i am doing wrong in this.
XML:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.5</ProductVersion>
<ProjectGuid>{6bc0a85b-9c15-41e6-874b-5fe07e5338e6}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>Installer</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;</DefineConstants>
<WixVariables>
</WixVariables>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>SourceDir=$(SolutionDir)XSSE\;ProductVersion=3.3.1.75;ProductName=XSSE;ToolchinShortcut=XSSEToolchinShortcut;ExtensionDir=XSSE;ManifestFileName=extension.vsixmanifest;PkageDefFileName=XSSE.ToolchainProvider.pkgdef;REGKEY=Software\Microsoft\XSSE;</DefineConstants>
<WixVariables>XYZ=123;</WixVariables>
</PropertyGroup>
<ItemGroup>
<Compile Include="filefragment.wxs" />
<Compile Include="Product.wxs" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUIExtension">
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
I think trying to capture the remainder of the line after the product version is unnecessary.
You don't need to worry about that. If your regex leaves the rest of the text alone, you can just replace the ProductVersion only.
I had success with this:
<replaceregexp file="${basedir}\Installer.wixproj"
match="ProductVersion=[0-9]+\.?[0-9]+\.?[0-9]+\.?[0-9]+\.?;"
replace="ProductVersion=${SpaceVersion};"
byline="true"
/>
You need to use \2 instead of \1.
<replaceregexp file="${basedir}\Installer.wixproj"
match="ProductVersion=([0-9].*);(.*)"
replace="ProductVersion=${SpaceVersion};\2"
byline="true"
/>
Standalone test:
<project default="test">
<property name="SpaceVersion" value="a.b.c"/>
<target name="test">
<replaceregexp file="test.xml"
match="ProductVersion=([0-9].*);(.*)"
replace="ProductVersion=${SpaceVersion};\2"
byline="true"
/>
</target>
</project>
Comparison of changed file with original:
$diff test.xml test.xml.0
2c2
< <DefineConstants>XXXXX;ProductVersion=a.b.c;YYYYY</DefineConstants>
---
> <DefineConstants>XXXXX;ProductVersion=20.323.23;YYYYY</DefineConstants>

Msbuild and SLN unbindig

I want to unbind my sln file from TFS server and publish it on SVN is there any "easy" option to do this. It's easy to open sln and chose unbind option in Visual Studio, but does any one ever tried to automate this process? There is a solution to edit sln file using xmlpoke and deleting binding information, but is it safe?
I have some samples published on the MSDN Code Gallery for the TFS 2010 SDK that illustrate how to do this with MSBuild and the MSBuild Community Tasks. Here's a snippet of MSBuild script from the WorkItemObjectModel sample's WorkItemType.csproj file:
<Import Project="$(MSBuildExtensionsPath32)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<ItemGroup>
<SourceFiles
Include="$(SolutionDir)**/*.*"
Exclude="$(SolutionDir)Package/**/*.*;$(SolutionDir)**/bin/**/*.*;$(SolutionDir)**/obj/**/*.*;$(SolutionDir)**/internal.proj;$(SolutionDir)**/*.*scc;$(SolutionDir)$(SolutionName).zip">
<Visible>False</Visible>
</SourceFiles>
</ItemGroup>
<Target Name="AfterBuild" Condition="'$(Configuration)'=='Release'"
Inputs="#(SourceFiles)" Outputs="$(SolutionDir)$(SolutionName).zip">
<Delete
Files="$(SolutionDir)$(SolutionName).zip"
Condition="Exists('$(SolutionDir)$(SolutionName).zip')" />
<PropertyGroup>
<PackageDir>$(SolutionDir)Package\</PackageDir>
</PropertyGroup>
<MakeDir
Directories="$(PackageDir)" />
<Copy
SourceFiles="#(SourceFiles)"
DestinationFiles="$(PackageDir)%(RecursiveDir)%(Filename)%(Extension)" />
<Delete
Files="$(PackageDir)**/bin/**/*.*;$(PackageDir)**/obj/**/*.*" />
<RemoveDir
Directories="$(PackageDir)**/bin;$(PackageDir)**/obj" />
<Attrib
Files="#(PackageFiles)"
ReadOnly="false" />
<FileUpdate
Files="$(PackageDir)$(SolutionFileName)"
IgnoreCase="true"
Regex="^\s+GlobalSection\(TeamFoundationVersionControl\).+\n(\s*Scc.*\n)+\s+EndGlobalSection"
ReplacementText=" "
Multiline="true"
Singleline="false" />
<ItemGroup>
<ProjectFiles Include="$(PackageDir)**/*.*proj" />
</ItemGroup>
<FileUpdate
Files="#(ProjectFiles)"
Regex="<Scc[A-z]+>.+</Scc[A-z]+>"
ReplacementText=" " />
<ItemGroup>
<PackageFiles Include="$(PackageDir)**\*.*" />
</ItemGroup>
<Zip
Files="#(PackageFiles)"
WorkingDirectory="$(PackageDir)"
ZipFileName="$(SolutionDir)$(SolutionName).zip" />
<Delete
Files="#(PackageFiles)" />
<RemoveDir
Directories="$(PackageDir)" />
</Target>
In a nutshell, this script copies the source files to a temporary directory, removes the source control bindings from the solution and project files, then zips up the sources and finally deletes the temporary directory.

Resources