MSBuild: ProjectReference Output Path in Wix Projects - msbuild

I'm trying to get the Output folder of referenced project in my Wix Visual Studio project, using MsBuild task. But it is failing with following error:
C:\Program Files
(x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(724,5):
error : The OutputPath property is not set for project
'ConsoleApplicatio n1.csproj'. Please check to make sure that you
have specified a valid combination of Configuration and Platform for
this project. Configuration='Release' Platfo rm='x86'. You may be
seeing this message because you are trying to build a project without
a solution file, and have specified a non-default Configuration or
Plat form that doesn't exist for this project.
[C:\Users\fwaheed\Documents\Visual Studio
2015\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cspro
j]
Following is the Target calling MsBuild task.
<Target Name="AfterBuild">
<MSBuild
Projects="#(ProjectReference)"
Targets="GetTargetPath"
BuildInParallel="false"
Condition="'%(Name)'=='ConsoleApplication1'" >
<Output TaskParameter="TargetOutputs" ItemName="DependentAssemblies" />
</MSBuild>
</Target>
Please note that same target worked perfectly if it is CSharp project, but failing in Wix project.
Can someone guide how to get ReferencedProjects output dirs in Wix Projects?
Thanks

You can try to see how Wix does it for passing the reference values to candle on build. They're in the wix2010.targets or wix200x.targets file. Unfortunately I don't have the time to really dig into this stuff but the properties these tasks set should still exist to be used in your AfterBuild target.
Just search for "ResolveReferences" in one of those targets files.
You can also just try setting
<OutputPath>somepathhere</OutputPath>
in your csproj file since msbuild is complaining that the property isn't set.

Related

How to change msbuild working directory in TFS 2013 workflow

I have a TFS 2013 build xaml workflow, that eventually calls the Microsoft.TeamFoundation.Build.Workflow.Activities.MSBuild activity once for each solution that I want to build. When msbuild.exe is called, it's working directory is the working directory of the current solution being built. I can see this through the 'MSBuildStartupDirectory' property when running msbuild with a 'diagnostic' verbosity.
Unfortunately, I need the working of msbuild.exe to be somewhere else when msbuild.exe starts. This is because I use the MSBuild SonarQube runner that imposes constraints on the directory from which msbuild is called.
I have looked at the 'msbuild' activity and there is no way to control the working directory. Is there another way to control the working directory of this activity?
Its been a while since I edited a build process template but I believe you could use an activity that just executes a command in CMD and provide the full MSBuild command. I'm sure there are tons of variables you will need to setup for this to work.
Instead of editing the build process template have you considered using a PowerShell script in the Post-build script to execute SonarQube?
I still haven't found any way to control the working directory of msbuild. But since I know that the working directory will be the directory of the project being built by msbuild, I created a new proj file at the root of my workspace (where my working directory has to be) and only build this new proj file from my workflow. This new proj file then builds all my other solutions. That way, my working directory is the same for all the solutions being built.
Here is an example of my top level proj file:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<ItemGroup>
<Solutions Include="**\*.sln"/>
</ItemGroup>
<Target Name="Build">
<MSBuild Projects="#(Solutions)" Targets="Build"/>
</Target>
</Project>
But beware that doing this may affect the output directory (OutDir) given to each solution. So you may want to do something like this:
<MSBuild Projects="#(Solutions)" Targets="Build" Properties="OutDir=$(OutDir)..\%(Solutions.Filename)"/>

MSBuild output missing javascript files compiled by Typescript

We use MSBuild on our CI server to compile our WebApp, however the build omits the JavaScript files built by TypeScript from the output of the build.
I would expect the output to contain the JavaScript and not the Typescript, however neither are in the output at the expected locations.
How can I include the JavaScript files without having to have them all in my solution? The TypeScript team seems to think this is bad, but I would rather not have duplicates of all the files in my solution either.
The problem was due to using MSBuild instead of the "Publish" on the build server it seems. I added an AfterBuild target to content include all of the JS files to the build output.
<Target Name="AfterBuild">
<ItemGroup>
<Content Include="**\*.js" />
</ItemGroup>
</Target>
Although this is not ideal, it allows the js files not to show in the solution when using visual studio and the files end up in the build output.
I tried many solutions from the web including the <Content Include="**\*.js" />, but nothing worked. I'm using MSBuild on my local dev box and typescript is installed and targets available in C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript.
It turns out my "old" MSBuild runner for web app csproj files is obsolete. I was doing this:
MSBuild.exe my.csproj /Target:ResolveReferences;_CopyWebApplication /property:WebProjectOutputDir=myfolder;OutDir=myfolder\bin;Configuration=Debug
but thanks to this post I need to use UseWPP_CopyWebApplication instead of the legacy _CopyWebApplication:
MSBuild.exe /t:Rebuild "/p:WebProjectOutputDir=myfolder;OutDir=myfolder\bin;Configuration=Debug;UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False" my.csproj
Now without any editing of the csproj file, all my TypeScript is included!
TypeScript is probably not installed on your build server. To install it, copy your TypeScript folder from c:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\ to the same folder on your build server (where v12 is the version of your Visual Studio).
The Visual Studio version on your build server can be different however. In my situation, the version on my development machine is v12, while the build server uses v11. I found that out by adding the following to the [WebProjectName].csproj file:
<Target Name="PrintVisualStudioInfo">
<Message Text="VisualStudioVersion: '$(VisualStudioVersion)'" Importance="High" />
</Target>
<PropertyGroup>
<CompileDependsOn>
PrintVisualStudioInfo;
$(CompileDependsOn)
</CompileDependsOn>
</PropertyGroup>
Be sure you put it after the last <Import /> element. Now when you look at the output of your build on the build server, you should see 'VisualStudioVersion: xx' somewhere.
Copy the TypeScript folder to the correct version folder on the build server.
Just adding in case it helps people.
We had this issue recently and it was fixed by adding
/p:VisualStudioVersion=12.0 to the BAT file :
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe FullBuild.proj /p:VisualStudioVersion=12.0 /t:createRelease /p:ReleaseNumber=5.22.0

How make MSBuild build custom target specified in csproj building sln?

I am facing an issue with MSBuild I can't overcome it by myself. As a result I rely on community's wisdom.
The real situation I'm having troubles with
I have a soluiton file containing several projects with dependencies to other projects in same solution. I'd like to append a custom target to one of the project's csproj file and build it from the command line. It will allow me to make all the necessary output binaries for this project for further processing during the building of the custom target. But the main thing is that I can't figure out how to do it, googling doesn't help either.
Simplification
To make thing simplier I decided to make a new C# console project, add a simple custom target to the project's file and try to make it build. Still no success! Here what I've done so far:
Created a solution app with a default console project coreapp. This gaves me at least two files:
app.sln
coreapp\coreapp.csproj
Modified coreapp.csproj with addition of my custom target inside of the Project tag
<Target Name="SampleTarget">
<Message Text="This is a SampleTarget" />
</Target>
Run on the command line the following command
%windir%\Microsoft.NET\framework\v3.5\msbuild.exe app.sln /t:coreapp:SampleTarget
or even
%windir%\Microsoft.NET\framework\v3.5\msbuild.exe app.sln /t:coreapp.csproj:SampleTarget
Results
No luck, facing the error
MSB4057: The target "coreapp.csproj:SampleTarget" does not exist in the project.
I suspect that MSBuild thinks somehting fundamentally different from what I want it to think...
BEsides that, I also tried to set on the same command line the environment variable MSBuildEmitSolution=1 to force msbuild dump a temporary solution file it creates while processing the solution. In this file, indeed, no such target. However I guess it isn't the reason because I asked msbuild to build coreapp.proj where target SampleTarget really resides.
The question is how to build SampleTarget in this simplified scenario using solution file since potencially it can contain dependencies for the project containing this SampleTarget target?
I'd be greatful for any sort of help or firection for further investigation!
Instead of inserting a custom target in your project file, you could try creating a new standalone msbuild file, which would:
build the solution file (which builds projects)
defines your extra target
Call it app-custom-Debug.msbuild , for example.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WorkingFolder>$(MSBuildProjectDirectory)</WorkingFolder>
<Configuration>Debug</Configuration>
<SolutionFile>app.sln</SolutionFile>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="Compile" />
<Target Name="Compile">
<Message Text="=== COMPILING $(Configuration) configuration ===" />
<MSBuild Projects="$(SolutionFile)"
Properties="Configuration=$(Configuration)" />
</Target>
<Target Name="SampleTarget">
<Message Text="This is a SampleTarget" />
</Target>
</Project>
Then you execute:
msbuild.exe app-custom-Debug.msbuild /t:SampleTarget
One option is to tie your SampleTarget to the standard Build targets via overriding the appropriate DependsOn property. In this case you could tell BeforeBuild that it DependsOn SampleTarget or you do the same thing with AfterBuild. This will ensure that MSBuild processes your target prior to the standard target indicated.

MSBuild working in debug mode, but not release mode - and another interesting anamoly

I have a basic MSBuild script which includes a step for project compilation/build. Looks like this:
....
<ItemGroup>
<ProjectReferences Include="loc1\Project1.csproj"/>
<ProjectReferences Include="loc2\Project2.csproj"/>
<ProjectReferences Include="loc3\Project3.csproj"/>
</ItemGroup>
....
<Target Name="BuildProjects">
<Message Text="Beginning main project build"/>
<MSBuild Projects="#(ProjectReferences)" Targets="Build" Properties="Configuration=$(Configuration);ProjectBuild=$(ProjectBuild);AppDir=$(AppDir)">
<Output TaskParameter="TargetOutputs" ItemName="AssembliesBuilt"/>
</MSBuild>
<!--<CallTarget Targets="BuildToolkit"/>-->
</Target>
Project3.csproj is a .NET 3.5 Web Services project. The configuration is passed in on the command line.
First was a problem with System.Linq not being able to be resolved; I remedied this by creating a reference to System.Core directly in the project file (apparently this happens often and requires this fix).
Now, when I build this project in debug mode, all is well. However, when trying to build in release mode, it fails like this, with may of these messages pertaining to all kinds of assemblies:
Considered "c:\Program Files (x86)\Reference Assemblies\Microsoft\VST040\v8.0\MyReferencedProjectAssembly.dll", but it didn't exist.
This happens many times over for a number of references. Oddly, after this happens, I switch back to debug mode and it fails to build again after the release mode happens. I have to remove the offending Project3 from the MSBuild file, run again (which works), and re-add the offending Project3 back into the file before it works again in debug mode.
I'm stumped. Any ideas?
It seems to me like your project references are not set up correctly. Your projects are build in the wrong build order and build failed "sometimes". It has nothing to do with debug/release mode, I guess.
Check your csproj files if it contains correct project references to other projects. For example if Project2 is depending on Project1:
project2.csproj:
<ProjectReference Include="..\loc1\Project1.csproj">
<Project>{79FB10A6-6CD9-46D4-9463-319B8CBD82FE}</Project>
<Name>Project1</Name>
</ProjectReference>
Where Project is ProjectGuid of project1 (from project1.csproj)

How do I add an MSBuild .proj file to my solution?

Does anyone know how to add a an MSBuild .proj file to my solution?
I was just given existing code from a vendor with a solution that references an MSBuild .proj file as one of its projects. When I open the solution, the project shows as (unavailable). It appears that I need to install some sort of project template to get this project to open correctly. I installed the Codeplex MSBuild Template, but this doesn't appear to be it.
Any ideas?
If you don't need IDE support, it's possible to do this using MSBuild solution extension targets.
Create a file named "before.SolutionName.sln.targets" with the following code:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectReference Include="CustomProject\CustomProject.proj">
<AdditionalProperties>Configuration=$(Configuration); Platform=AnyCPU</AdditionalProperties>
<Configuration>$(Configuration)</Configuration>
<Platform>AnyCPU</Platform>
</ProjectReference>
</ItemGroup>
</Project>
When your solution is built at command line by MSBuild (ie/ build server) the custom MSBuild project will be pulled into the temporary in-memory project file that MSBuild converts the solution into.
I actually got it to work! I re-started Visual Studio and still saw that the projects were unavailable after installing the MSBuild Template mentioned above. I had to manually reload the projects. That fixed the issue.