3

I need to call exec and build a wix setup project.

Currently I have the following in my TFSbuild.proj

 <PropertyGroup>
      <WebRoot>$(DropLocation)\Latest\x86\Release\_PublishedWebsites\Web</WebRoot> 
      <DBRoot>$(DropLocation)\Latest\x86\Release\Database</DBRoot> 
    </PropertyGroup>

 <PropertyGroup>
      <Msbuildexe>&quot;msbuild&quot;</Msbuildexe>
      <Configuration>&quot;/p:Configuration:&quot;Release&quot;&quot;</Configuration>
      <DefineConstants>&quot; /p:DefineConstants:&quot;WebRoot=$(WebRoot);DBRoot=$(DBRoot)&quot;&quot;</DefineConstants>
      <WixSolution>&quot;$(MSBuildProjectDirectory)\Setup\Setup.sln&quot;</WixSolution>
    </PropertyGroup>

    <Message Text="Bulding setup solution" />
    <Message Text="$(Msbuildexe) $(Configuration) $(DefineConstants) $(WixSolution)" />
    <Exec Command="$(Msbuildexe) $(Configuration) $(DefineConstants) $(WixSolution)" />

I've tried to simply as much as possible so I don't get confused where the " are meant to be. When I run this the debug message (2nd last command) outputs

"msbuild" "/p:Configuration:"Release"" " /p:DefineConstants:"WebRoot=\server\drops\app\Installer Build\Latest\x86\Release_PublishedWebsites\Web;DBRoot=\server\drops\app\Installer Build\Latest\x86\Release\Database"" "f:\builds\app\Installer Build\BuildType\Setup\Setup.sln"

And I get the following error in the log

'"msbuild"' is not recognized as an internal or external command,
operable program or batch file. f:\builds\app\Installer Build\BuildType\TFSBuild.proj(538,5): error MSB3073: The command ""msbuild" "/p:Configuration:"Release"" " /p:DefineConstants:"WebRoot=\server\drops\app\Installer Build\Latest\x86\Release_PublishedWebsites\Web;DBRoot=\server\drops\app\Installer Build\Latest\x86\Release\Database"" "f:\builds\app\Installer Build\BuildType\Setup\Setup.sln"" exited with code 9009.

I'm not sure if this is being caused by not being able to call the msbuild command from the command line or a " issue. If it is because I can't call msbuild from the command line like this how would I go about referencing it, is there a property that points to it?

Daniel Powell
  • 8,143
  • 11
  • 61
  • 108
  • I might miss something but why do you need to `Exec` MSBuild instead of just adding a [MSBuild Task](http://msdn.microsoft.com/en-us/library/z7f65y0d.aspx)? – Filburt Jun 29 '11 at 15:01

2 Answers2

1

To start with, you don't need most of the quotes, especially if the paths you are using don't contain spaces, but I'd trim it down to this, allowing for spaces in the paths for $(WebRoot), $(DbRoot) and $(MSBuildProjectDirectory):

<PropertyGroup>
   <WebRoot>$(DropLocation)\Latest\x86\Release\_PublishedWebsites\Web</WebRoot>
   <DBRoot>$(DropLocation)\Latest\x86\Release\Database</DBRoot>
</PropertyGroup>
<PropertyGroup>
   <MsbuildExe>{still-needs-a-path-to}\msbuild</MsbuildExe>
   <Configuration>/p:Configuration:Release</Configuration>
   <DefineConstants>/p:DefineConstants:&quot;WebRoot=$(WebRoot);DBRoot=$(DBRoot)&quot;</DefineConstants>
   <WixSolution>&quot;$(MSBuildProjectDirectory)\Setup\Setup.sln&quot;</WixSolution>
</PropertyGroup>
<Message
   Text="Bulding setup solution"
   />
<Message
   Text="$(MsbuildExe) $(Configuration) $(DefineConstants) $(WixSolution)"
   />
<Exec
   Command="$(MsbuildExe) $(Configuration) $(DefineConstants) $(WixSolution)"
   />

However, you still won't be able to execute MSBuild with this, since the path to MSBuild isn't specified. It is typically found in the $(WINDIR)\Framework\Microsoft.Net\v4.0.30319 folder. There are a few ways to get this, either encode it directly, rely on an environment variable (that has to be set up somehow), use the predefined $(MSBuildBinPath), or extract it from the registry using the MSBuild registry syntax, which would look like this:

$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath)

However, it isn't clear why you are running MSBuild using Exec rather than just using the MSBuild task. Change the line with Exec to this:

<MSBuild
   Project="$(WixSolution)"
   Properties="$(DefineConstants)"
   />

removing your declaration for <Configuration> and changing <DefineConstants> to this:

   <DefineConstants>Configuration=$(Configuration);WebRoot=$(WebRoot);DBRoot=$(DBRoot)</DefineConstants>
Brian Kretzler
  • 9,748
  • 1
  • 31
  • 28
  • define constants is a list of properties itself that I actually need to override and it seems the msbuild task cant handle this...see http://stackoverflow.com/questions/506687/defining-multiple-values-in-defineconstants-in-msbuild-element . Thanks for the answer! – Daniel Powell Jun 29 '11 at 05:31
  • and I dont think I can use the workaround proposed there as we are using tfs 2008 which I think uses msbuild 3.5? Even though I would be calling the 4.0 msbuild in the exec task the msbuild that executes it would be 3.5 I would think? Could be wrong though! – Daniel Powell Jun 29 '11 at 05:42
  • If you are using 3.5, then the path would be v3.5 instead of v4.0.30319, and the registry path would have 3.5 instead of 4.0, but otherwise it would work the same. MSBuild can handle overriding the individual properties that make up DefineConstants, or the entire value, just use a condition like Condition="'$(DefineConstants)' == ''" and the redeclaration will be skipped if the property already has a value. – Brian Kretzler Jun 29 '11 at 06:04
  • ...oh yeah, forgot to add $(MSBuildBinPath), which is a reserved property with the path, I've added that to the above. – Brian Kretzler Jun 29 '11 at 06:06
0

Following up on my comment I'd suggest you try using the MSBuild Task instead of Exec:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="BuildWiXSolution">
    <!-- Include the custom build targets installed with WiX -->
    <Import Project="$(MSBuildExtensionsPath)\Wix\Wix.targets"/>

    <PropertyGroup>
        <WebRoot>$(DropLocation)\Latest\x86\Release\_PublishedWebsites\Web</WebRoot> 
        <DBRoot>$(DropLocation)\Latest\x86\Release\Database</DBRoot> 
    </PropertyGroup>

    <ItemGroup>
        <WiXSolution Include="$(MSBuildProjectDirectory)\Setup\Setup.sln">
            <Properties>Configuration=Release</Properties>
            <AdditionalProperties>WebRoot=$(WebRoot);DBRoot=$(DBRoot)</AdditionalProperties>
        </WiXSolution>
    </ItemGroup>

    <Target Name="BuildWiXSolution">
        <MSBuild Projects="@(WiXSolution)" />
    </Target>  
</Project>

It allows you to keep configuration properties and additional properties together with your Wix solution.

Filburt
  • 17,626
  • 12
  • 64
  • 115
  • the additional properties wont work I believe, as DefineConstants is actually a property with a list of properties defined within it – Daniel Powell Jun 29 '11 at 23:24
  • @Daniel It should be possible to wrap `DefineConstants` up like in your code sample - I just shortend it down for readablity. – Filburt Jun 30 '11 at 07:05