TFS CI issue with a SSIS package - continuous-integration

Build started 16/11/2011 9:24:11 AM.
Project "C:\Builds\1\NetTellerMigration\NetTellerMigrationBuild\Sources\blah.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
Building solution configuration "Development|Default".
MSBUILD : warning MSB4078: The project file "blah\blah.dtproj" is not supported by MSBuild and cannot be built. [C:\Builds\1\NetTellerMigration\NetTellerMigrationBuild\Sources\blah.sln]
Done Building Project "C:\Builds\1\NetTellerMigration\NetTellerMigrationBuild\Sources\blah.sln" (default targets).
Build succeeded.
"C:\Builds\1\NetTellerMigration\blahBuild\Sources\blah.sln" (default target) (1) ->
(blah_b target) ->
MSBUILD : warning MSB4078: The project file "blah\blah.dtproj" is not supported by MSBuild and cannot be built. [C:\Builds\1\NetTellerMigration\NetTellerMigrationBuild\Sources\blah.sln]
1 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.42
I currently have tfs2010 installed with SqlExpress and im trying 'unsucessfully' to implement continuous-integration against a SSIS package. My aim is to create a build triggered by a code checkin. I have a build definition to doso but the warning shown above is displayed and no '.dtsx' files are copied to the build directory?
I believe its something to do with the build agent targeting v4 of the .net framework but I could be wrong. Anyway, any help would be much appreciated from anyone who has experience this problem before.

MSBuild can't build SSIS projects (.dtproj) because the format of these projects is pre-VS2010. The best thing to do here is to have MSBuild shell out to the SSIS project. You can create an empty C# project to do this. Then, open the .csproj file for the new project in a text editor and set the BeforeBuild target to the following:
<Target Name="BeforeBuild">
<!-- Build the analysis SSIS project -->
<Exec Command=""$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\#InstallDir)\devenv.exe" blah\blah.dtproj /Build" />
</Target>
Adjust the blah/blah.dtproj path for your project. This will run the VS2008 version of devenv to build the SSIS project.
Below is a sample of what the whole .csproj file might look like:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
<PropertyGroup>
<OutputPath>Bin</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="BeforeBuild">
<!-- Build the analysis SSIS project -->
<Exec Command=""$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\#InstallDir)\devenv.exe" blah\blah.dtproj /Build" />
</Target>
</Project>

I had to slightly tweek my target to get it working:
<Target Name="BeforeBuild">
<!-- Build the analysis SSIS project -->
<Exec Command=""$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\#InstallDir)devenv.exe" "$(SolutionPath)" /Build "Release|Any CPU" /project projectFileName.dtproj" />
</Target>

Related

How to build project in multiple configurations to automate the build process?

I have a solution, which contains a native project. For the main project to properly work, the following steps should be taken:
The native project has to be built in Release/x86 configuration
The native project has to be built in Release/x64 configuration
All .NET projects have to be built
Both binaries from steps 1 and 2 have to be placed in the main project's output folder.
Is there a way to configure project, so that all of those steps happen upon simply choosing "Build | Rebuild all"? I know of the batch build option, but I'd still have to execute step 4 manually.
I think you have to use msbuild script to build your project rather than VS IDE. Scripts are more flexible and can realize your requirements.
1) create a new file called build.proj and then add these on that file:
<Project>
<ItemGroup>
<!--include all c# csproj files to build these projects all at once-->
<NetProjectFile Include="**\*.csproj" />
<!--include the c++ proj files-->
<NativeProjectFile Include="**\*.vcxproj" />
</ItemGroup>
<Target Name="Build">
<MSBuild Projects="#(NetProjectFile)" Targets="Restore;Build" Properties="Configuration=Debug;Platform=AnyCPU"/>
<!--OutDir is the path of the execute file ,pdb.... if you also want the intermediate files to be in the same folder, you should also use IntDir -->
<MSBuild Projects="#(NativeProjectFile)" Targets="Build" Properties="Configuration=Release;Platform=x86;OutDir=xxx\xxx\"/>
<MSBuild Projects="#(NativeProjectFile)" Targets="Build" Properties="Configuration=Release;Platform=x64;OutDir=xxx\xxx\"/>
</Target>
</Project>
3) Just run msbuild build.proj -t:Build to get what you want.

Difficulty using <Import> to modularize a Visual Studio project file

I'm attempting to modularize a Visual Studio project file, but it's not working. This is for Visual Studio 2008 with .Net 3.5.
Shown below, the first example works, but the second one does not. How can I make it work..?
I'm new to this topic and probably missing something. I first became aware of it while reading a 3rd-party blog, and then found it in the documentation too. I've googled for more help, but there's too much information for me to find a relevant answer.
The main project file:
...
<!-- main project file -->
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<Target Name="AfterBuild">
<Message Text="This is a message from the *.vbproj file."/> ... this works
</Target>
</Project>
...but if <Import> is used, with the same <Target> and <Message> in the imported file, it doesn't work. MSBuild seems to process everything correctly, but nothing happens...
The main project file:
...
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<Import Project="$(MSBuildProjectDirectory)\CustomBuildEvents.targets" /> ... new tag
<Target Name="AfterBuild">
<Message Text="This is a message from the *.vbproj file."/> ... this still works
</Target>
</Project>
The imported targets file:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="AfterBuild">
<Message Text="Hello from the imported file." Importance ="high"/> ... doesn't work
</Target>
</Project>
And the build output, with Verbosity set to Diagnostic:
### Halfway through the output, this is the only mention of the imported file. ###
None
CustomBuildEvents.targets ... custom file
My Project\Application.myapp
My Project\Settings.settings
### And then at the end, no mention of the imported file or its message. ###
Done building target "CoreBuild" in project "MsBuildCustomTargetTester.vbproj".
Target "AfterBuild" in file "C:\Visual Studio 2008\Solutions\MsBuildCustomTargetTester\MsBuildCustomTargetTester\MsBuildCustomTargetTester.vbproj":
Task "Message"
Hello from the *.vbproj file. ... message from main file
Done executing task "Message".
Done building target "AfterBuild" in project "MsBuildCustomTargetTester.vbproj".
Target "Build" in file "c:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets":
Building target "Build" completely.
No input files were specified.
Done building target "Build" in project "MsBuildCustomTargetTester.vbproj".
Done building project "MsBuildCustomTargetTester.vbproj".
Project Performance Summary:
109 ms C:\Visual Studio 2008\Solutions\MsBuildCustomTargetTester\MsBuildCustomTargetTester\MsBuildCustomTargetTester.vbproj 1 calls
The problem with AfterBuild is that it can only be defined once. So if you import it and then later in the project file define it again, the last definition wins and becomes the only definition.
To solve this you need to use the more advanced way to register events. Given that you are using Visual Studio 2008 (WHY?!), you need to use the more advanced syntax for your custom targets files:
<Project>
<!--
Redefines the original build order, includes the standard targets and
adds your new custom target to the end of the list.
-->
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
CustomTarget
</BuildDependsOn>
</PropertyGroup>
<CustomTarget>
<!-- Imported after Build -->
<Message Text="Hello from the imported file." Importance ="high"/>
</CustomTarget>
</Project>
There are other ways to do this which were introduced in MsBuild 4 with the BeforeTargets and AfterTargets attributes on any target, but If I'm remembering correctly the above syntax should also work with the version of MsBuild that ships with Visual Studio 2008.
See also:
What is the difference between 'DependsOnTargets' and 'AfterTargets'?
https://blogs.msdn.microsoft.com/msbuild/2006/02/10/how-to-add-custom-process-at-specific-points-during-build-method-2/

How do I use an MSBuild file from Visual Studio 2012?

I have a simple MSBuild file that I'm learning with.
Here it is:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Clean" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{D5A16164-962E-4A6D-9382-240F31AB6C50}</ProjectGuid>
</PropertyGroup>
<Target Name="Clean">
<ItemGroup>
<BinFiles Include="bin\*.*" />
<fff Include="f\*.*" />
</ItemGroup>
<Delete Files="#(BinFiles)" />
<Delete Files="#(fff)" />
</Target>
</Project>
Now I want to include this in a Visual Studio solution and be able to run the "clean" target from Visual Studio 2012. I tried naming it testproject.msbuildproj like the internet seems to suggest "works", but it doesn't work. When I run the clean command I just get "unexpected error".
If I rename the project to testproject.csproj, it does some unintuitive things like creating compilation directories, but it does actually run my clean command properly. However, this is undesireable because it creates obj and bin/x86/debug type directories. It also looks goofy in Visual Studio because it still gives the References drop down.
How can I use just a plain vanilla MSBuild project from Visual Studio without random errors or false assumptions?
Note I only am having a problem with this from Visual Studio. Using msbuild from the command line it works perfectly
Visual Studio creates bin / obj folders when it opens csproj file. When you click Build / Rebuild / Clean it just uses appropriate targets from the project file.
You cannot stop VS from creating these folders, but you can ask it to create them in say temp folder by setting appropriate properties - refer this MSDN article for details.
So the steps are to rename your project to csproj, and add the following lines into project:
<PropertyGroup>
<OutputPath>$(Temp)\bin</OutputPath>
<IntermediateOutputPath>$(Temp)\obj</IntermediateOutputPath>
</PropertyGroup>
I usually use a bit different approach to work with MSBUILD files from VS:
I use regular csproj file with removed Import ... CSharp.targets part as pure container for my Build projects.
I add actual build files with targets and logic, and all properties, necessary artifacts like XSLT etc using "Include into project", so I can manage hierarchy and change any file from within VS.Net.
I redefine Build / Rebuild targets in csproj file for whatever I need, for example Build may contain minimum output, and while rebuild diagnostic one.
Like this:
<Target Name="Build">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe Builds\build.proj /t:Build /v:m" />
</Target>
<Target Name="Rebuild">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe Builds\build.proj /t:Build /v:d" />
</Target>

Build doesn't work from VisualStudio, but is ok from msbuild

From a brand new console application template in visual studio, I edited the .csproj to build another project like this:
...
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="BeforeBuild">
<MSBuild Projects=".\other.mproj"/>
</Target>
...
Where other.mproj is:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<Target Name="Build">
<Message Text="kikou" />
</Target>
</Project>
After a while I discovered that modifying the content of other.mproj (for instance, by introducing errors or changing text kikou to something else) would not be taken into account unless unloading/reloading the project in visual studio.
Building from the command line with 'msbuild myproj.csproj' immediatly detect changes in 'other.mproj'. So it all looks like visual studio is working from a cached version of other.mproj file.
Why is visual studio caching this other script (which is even not included to the project), and how can I solve this issue ?
Update: I also tried this UseHostCompilerIfAvailable, it doesn't work.
NB1: I didn't add other.mproj as a project reference in the .csproj because it is not a .NET project at all (it just creates resources files for the .csproj from other inputs before the build)
NB2: I'm using VS2010 (10.0.10219.1SP1Rel + MSBuild 4.0.30319.1)
Visual Studio caches all MSBuild files, this is done for performance reasons. You will not be able to have an MSBuild only way around this. It may be possible to achieve this via a VS add-in but I'm not 100% sure of that.

How can I debug an MSBuild file?

I've got a large solution that I'm using TFS (and MSBuild) to... well... build. However, it takes a long time to build everything, and I was wondering if it was possible to just debug the build XML file rather than doing the build itself.
I'm using VS2008 and TFS 2008.
Unfortunately the possibility to debug MSBuild scripts with Visual Studio has been unofficially introduced in .NET 4.0.
For earlier versions all you are left with is "debugging by tracing", that is inserting log statements at key points in your script, running the script and examining the output.
Here's how you would typically do it using the Message Task:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SomeVariable>foo</SomeVariable>
</PropertyGroup>
<Target Name="MyTarget">
<!-- Some tasks -->
<Message Text="The value of SomeVariable is: $(SomeVariable)" Importance="High" />
<!-- Some tasks -->
</Target>
</Project>
You can then invoke the script from the command line and redirect the output to a log file:
msbuild MyScript.proj /t:MyTarget > %USERPROFILE%\Desktop\MyScript.log
Related resources:
Debugging MSBuild scripts with Visual Studio (.NET 4.0)
Overview of Logging in MSBuild

Resources