In the Life of a TFS Configuration Manager Part 1: Building Projects that are not Supported by MSBuild

You have probably had the following error:

The project file … is not supported by MSBuild and cannot be built.

Well, it is a common problem that Visual Studio Installation projects (.vdproj) cannot be built using MSBuild, and neither can Business Intelligence Development Studio (BIDS) projects (.dwproj, .dtproj, .rptproj). A common solution seems to be to install Visual Studio on the build server and use DevEnv by modifying the build template. I used the following blog post as a starting point: I need to build a project that is not supported by MSBuild

I made the following modifications:

1. Create a string new variable called ProgramToInvoke in the Compile the Project scope. Set default to “”.

2. Extend the switch with .rptproj, .dwproj and .dtproj. For these, set ProgramToInvoke to “C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com” . (Include the .com extension to be sure that is run rather tan DevEnv.exe. The devenv.com utility provides for the delivery of output through standard system streams, such as stdout and stderr.) For .vdproj, set ProgramToInvoke to “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com” .

image

3. Under this activity, insert an if activity with condition ProgramToInvoke = “”. In the Then branch, place the Run MSBuild for Project activity.

image

4. In the Else branch, add a sequence activity called Build Using DevEnv. Here you place the InvokeProcess activity.

5. Set [ExitCode] as result to be able to test the result of the build.

image

6. Now add a condition that checks if [ExitCode] <> 0. If so, something went wrong. I discovered that sometimes it goes wrong without any good reason, and the solution is to retry the operation once more. Therefore, add the same Invoke DevEnv activity again.

image

If it fails a second time, set the build Status property to Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed.

7. In the CopyDirectory activity, copy the results to BinariesDirectory plus the configuration to be built.

image

Here is the entire source code:

                                      <Sequence DisplayName="Compile the Project" sap:VirtualizedContainerService.HintSize="980,1635" mtbwt:BuildTrackingParticipant.Importance="Low">
                                        <Sequence.Variables>
                                          <Variable x:TypeArguments="x:String" Name="localProject" />
                                          <Variable x:TypeArguments="x:Int32" Name="ExitCode" />
                                          <Variable x:TypeArguments="x:String" Name="ProgramToInvoke">
                                            <Variable.Default>
                                              <Literal x:TypeArguments="x:String" Value="" />
                                            </Variable.Default>
                                          </Variable>
                                        </Sequence.Variables>
                                        <sap:WorkflowViewStateService.ViewState>
                                          <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                                            <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                          </scg:Dictionary>
                                        </sap:WorkflowViewStateService.ViewState>
                                        <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" sap:VirtualizedContainerService.HintSize="958,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[serverBuildProjectItem]" Result="[localProject]" Workspace="[Workspace]" />
                                        <Switch x:TypeArguments="x:String" DisplayName="Determine project type" Expression="[(New System.IO.FileInfo(localProject)).Extension.ToLower()]" sap:VirtualizedContainerService.HintSize="958,298">
                                          <sap:WorkflowViewStateService.ViewState>
                                            <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                              <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                              <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                                            </scg:Dictionary>
                                          </sap:WorkflowViewStateService.ViewState>
                                          <Assign x:Key=".vdproj" sap:VirtualizedContainerService.HintSize="453,100">
                                            <Assign.To>
                                              <OutArgument x:TypeArguments="x:String">[ProgramToInvoke]</OutArgument>
                                            </Assign.To>
                                            <Assign.Value>
                                              <InArgument x:TypeArguments="x:String">C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com</InArgument>
                                            </Assign.Value>
                                          </Assign>
                                          <Assign x:Key=".rptproj" sap:VirtualizedContainerService.HintSize="453,100">
                                            <Assign.To>
                                              <OutArgument x:TypeArguments="x:String">[ProgramToInvoke]</OutArgument>
                                            </Assign.To>
                                            <Assign.Value>
                                              <InArgument x:TypeArguments="x:String">C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com</InArgument>
                                            </Assign.Value>
                                          </Assign>
                                          <Assign x:Key=".dwproj" sap:VirtualizedContainerService.HintSize="453,100">
                                            <Assign.To>
                                              <OutArgument x:TypeArguments="x:String">[ProgramToInvoke]</OutArgument>
                                            </Assign.To>
                                            <Assign.Value>
                                              <InArgument x:TypeArguments="x:String">C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com</InArgument>
                                            </Assign.Value>
                                          </Assign>
                                          <Assign x:Key=".dtproj" sap:VirtualizedContainerService.HintSize="453,100">
                                            <Assign.To>
                                              <OutArgument x:TypeArguments="x:String">[ProgramToInvoke]</OutArgument>
                                            </Assign.To>
                                            <Assign.Value>
                                              <InArgument x:TypeArguments="x:String">C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com</InArgument>
                                            </Assign.Value>
                                          </Assign>
                                        </Switch>
                                        <If Condition="[ProgramToInvoke = &quot;&quot;]" sap:VirtualizedContainerService.HintSize="958,1111">
                                          <If.Then>
                                            <mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" sap:VirtualizedContainerService.HintSize="200,1010" LogFileDropLocation="[logFileDropLocation]" OutDir="[outputDirectory]" Platform="[platformConfiguration.Platform]" Project="[localProject]" RunCodeAnalysis="[RunCodeAnalysis]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
                                          </If.Then>
                                          <If.Else>
                                            <Sequence DisplayName="Build Using DevEnv" sap:VirtualizedContainerService.HintSize="733,1010">
                                              <sap:WorkflowViewStateService.ViewState>
                                                <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                  <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                                                  <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                                </scg:Dictionary>
                                              </sap:WorkflowViewStateService.ViewState>
                                              <mtbwa:InvokeProcess Arguments="[&quot;&quot;&quot;&quot; + localProject + &quot;&quot;&quot; /build &quot; + platformConfiguration.Configuration]" DisplayName="Invoke DevEnv" FileName="[ProgramToInvoke]" sap:VirtualizedContainerService.HintSize="711,190" Result="[[ExitCode]]">
                                                <mtbwa:InvokeProcess.ErrorDataReceived>
                                                  <ActivityAction x:TypeArguments="x:String">
                                                    <ActivityAction.Argument>
                                                      <DelegateInArgument x:TypeArguments="x:String" Name="errOutput" />
                                                    </ActivityAction.Argument>
                                                    <mtbwa:WriteBuildError sap:VirtualizedContainerService.HintSize="200,22" Message="[errOutput]" />
                                                  </ActivityAction>
                                                </mtbwa:InvokeProcess.ErrorDataReceived>
                                                <mtbwa:InvokeProcess.OutputDataReceived>
                                                  <ActivityAction x:TypeArguments="x:String">
                                                    <ActivityAction.Argument>
                                                      <DelegateInArgument x:TypeArguments="x:String" Name="stdOutput" />
                                                    </ActivityAction.Argument>
                                                    <mtbwa:WriteBuildMessage sap:VirtualizedContainerService.HintSize="200,22" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" Message="[stdOutput]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" />
                                                  </ActivityAction>
                                                </mtbwa:InvokeProcess.OutputDataReceived>
                                                <sap:WorkflowViewStateService.ViewState>
                                                  <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                    <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                                  </scg:Dictionary>
                                                </sap:WorkflowViewStateService.ViewState>
                                              </mtbwa:InvokeProcess>
                                              <If Condition="[[ExitCode] &lt;&gt; 0]" DisplayName="" sap:VirtualizedContainerService.HintSize="711,656">
                                                <sap:WorkflowViewStateService.ViewState>
                                                  <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                    <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                                  </scg:Dictionary>
                                                </sap:WorkflowViewStateService.ViewState>
                                                <If.Then>
                                                  <Sequence sap:VirtualizedContainerService.HintSize="486,555">
                                                    <sap:WorkflowViewStateService.ViewState>
                                                      <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                                                      </scg:Dictionary>
                                                    </sap:WorkflowViewStateService.ViewState>
                                                    <mtbwa:InvokeProcess Arguments="[&quot;&quot;&quot;&quot; + localProject + &quot;&quot;&quot; /build &quot; + platformConfiguration.Configuration]" DisplayName="Invoke DevEnv" FileName="[ProgramToInvoke]" sap:VirtualizedContainerService.HintSize="464,190" Result="[[ExitCode]]">
                                                      <mtbwa:InvokeProcess.ErrorDataReceived>
                                                        <ActivityAction x:TypeArguments="x:String">
                                                          <ActivityAction.Argument>
                                                            <DelegateInArgument x:TypeArguments="x:String" Name="errOutput" />
                                                          </ActivityAction.Argument>
                                                          <mtbwa:WriteBuildError sap:VirtualizedContainerService.HintSize="200,22" Message="[errOutput]" />
                                                        </ActivityAction>
                                                      </mtbwa:InvokeProcess.ErrorDataReceived>
                                                      <mtbwa:InvokeProcess.OutputDataReceived>
                                                        <ActivityAction x:TypeArguments="x:String">
                                                          <ActivityAction.Argument>
                                                            <DelegateInArgument x:TypeArguments="x:String" Name="stdOutput" />
                                                          </ActivityAction.Argument>
                                                          <mtbwa:WriteBuildMessage sap:VirtualizedContainerService.HintSize="200,22" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" Message="[stdOutput]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" />
                                                        </ActivityAction>
                                                      </mtbwa:InvokeProcess.OutputDataReceived>
                                                      <sap:WorkflowViewStateService.ViewState>
                                                        <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                          <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                                        </scg:Dictionary>
                                                      </sap:WorkflowViewStateService.ViewState>
                                                    </mtbwa:InvokeProcess>
                                                    <If Condition="[[ExitCode] &lt;&gt; 0]" DisplayName="" sap:VirtualizedContainerService.HintSize="464,201">
                                                      <sap:WorkflowViewStateService.ViewState>
                                                        <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                          <x:Boolean x:Key="IsPinned">False</x:Boolean>
                                                        </scg:Dictionary>
                                                      </sap:WorkflowViewStateService.ViewState>
                                                      <If.Then>
                                                        <mtbwa:SetBuildProperties DisplayName="Set Status to Failed" sap:VirtualizedContainerService.HintSize="219,100" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="Status" Status="[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]" />
                                                      </If.Then>
                                                      <If.Else>
                                                        <mtbwa:CopyDirectory Destination="[BinariesDirectory + &quot;\&quot; + platformConfiguration.Configuration]" sap:VirtualizedContainerService.HintSize="220,100" Source="[(New System.IO.FileInfo(localProject)).DirectoryName + &quot;\&quot; + platformConfiguration.Configuration + &quot;\&quot;]" />
                                                      </If.Else>
                                                    </If>
                                                  </Sequence>
                                                </If.Then>
                                                <If.Else>
                                                  <mtbwa:CopyDirectory Destination="[BinariesDirectory + &quot;\&quot; + platformConfiguration.Configuration]" sap:VirtualizedContainerService.HintSize="200,555" Source="[(New System.IO.FileInfo(localProject)).DirectoryName + &quot;\&quot; + platformConfiguration.Configuration + &quot;\&quot;]" />
                                                </If.Else>
                                              </If>
                                            </Sequence>
                                          </If.Else>
                                        </If>
                                      </Sequence>
Advertisements

2 thoughts on “In the Life of a TFS Configuration Manager Part 1: Building Projects that are not Supported by MSBuild”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s