Nant script not able to spawn msbuild - msbuild

I've been asked to migrate a VB.NET solution from Windows Server 2003, Visual Studio 2005, 32 bit, .NET 2.0 to Windows Server 2008, Visual Studio 2008, 64 bit, .NET 4.0. I have the solution compiling and working fine in Visual Studio. the next step is getting the Nant script to work so it'll checkout, compile and test like it did before.
However, when the Nant script gets to the msbuild step, it's failing immediately with "...Microsoft.NET/Framework64/v4.0.30319/msbuild failed to start. Access is denied"
I've tried running msbuild directly with the same inputs and it gets past this point. My question is: is there something I can put in my nant .build to get it to run it's tasks as an administrator?
My .build file:
<?xml version="1.0"?>
...
<credential domain="xxxx" username="xxxxx" password="xxxxxx" id="55" />
<property name="debug" value="true" overwrite="false" />
<property name="configuration" value="debug" overwrite="false" />
<property name="solution.file" value="solution.sln" overwrite="false" />
...
<target name="msbuild" description="Build the whole solution">
<exec program="C:/Windows/Microsoft.NET/Framework64/v4.0.30319/msbuild" workingdir="D:/BuildTest" commandline='"${solution.file}" /v:q /nologo /p:Configuration=${configuration}' />
</target>
...

Or
You could put ".exe" on the end if the msbuild line
<exec program="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe">

I have the same problem on a 32-bit machine. A workaround for me is to use nantcontrib's msbuild task instead. Anyone understands why this works?
On a 64-bit computer the exec-method works as well. I have to point to msbuild.exe in the correct Framework folder.
<target name="compile" description="Compiles the .Net solution">
<!-- this works -->
<msbuild project="${src.root.dir}\${src.solution}"
verbosity="Normal">
<arg value="/p:Configuration=${msbuild.configuration}" />
<arg value="/p:Platform=Any CPU" />
<arg value="/t:Rebuild" />
<arg value="/nologo" />
</msbuild>
<!-- access is denied -->
<exec program="${msbuild.path}"
workingdir="${src.root.dir}"
basedir="${src.root.dir}"
commandline="${src.root.dir}\${src.solution}${src.solution}"
failonerror="true" >
<arg value="/p:Platform=Any CPU" />
<arg value="/p:Configuration=${msbuild.configuration}" />
<arg value="/t:Rebuild" />
<arg value="/v:${msbuild.verbosity}" />
</exec>
</target>

Related

Apache Ant "SI command" for MKStask

Upon trying to use the MKS task for apache ant, I need to specify the application executing the command. In the documentation I found, it says for example "si" or "im". I'm a little confused at this considered ant is used from command prompt so I'm not sure which application would be doing said command, nor do I know what applications "si" or "im" might be. I am using this task to try and send and receive build info to Integrity if that is pertinent. I was able to find this CLI reference guide for Integrity (link at bottom) which only uses im as a prefix, so I'm thinking that's the one I want to use, but I would appreciate an explanation as to what application im indicates (possible Integrity -something) and what one would specify with "si". Thanks
https://bugs.eclipse.org/bugs/attachment.cgi?id=52225
The si commands are used for Source Integrity tasks (the SCCM side of things), while the im commands are used for Integrity Manager commands (the workflow and document management side of things).
The Integrity client should have man page support on all platforms, so you should be able to run man im or man si to see a breakdown of all the supported commands.
In addition, with newer releases of the client, pressing F1 should get you a help interface, which includes documentation on CLI commands.
The guide to the link you posted is a very old version of the product CLI reference, and only for the im commands.
Since you're talking about using Ant, I'm assuming you're trying to perform builds, which will mostly involve si commands (creating sandboxes, checking out members, etc.).
Here are a couple examples of using si in ant:
<target name="check.mks.conn">
<echo message="Checking if an MKS connection exists. If not, one will be created." />
<exec executable="si" failonerror="true">
<arg line="connect" />
<arg line="--hostname=${mks.server}" />
<arg line="--port=${mks.port}" />
<arg line="--user=${mks.user}" />
<arg line="--gui" />
</exec>
</target>
<!-- =================================================================== -->
<!-- If the sandbox already exists, resync the files -->
<!-- Manually drop any empty folders as resync does not do this. -->
<!-- =================================================================== -->
<target name="resync.sandbox" unless="clean.build">
<exec executable="si" failonerror="true">
<arg line="resync" />
<arg line="--hostname=${mks.server}" />
<arg line="--port=${mks.port}" />
<arg line="-R" />
<arg line="-f" />
<arg line="-Y" />
<arg line="-S ${basedir}\${prj.name}\project.pj" />
</exec>
<delete includeemptydirs="true">
<fileset dir="${prj.name}" excludes="**\*.*" />
</delete>
</target>
<!-- =================================================================== -->
<!-- Drop and recreate the sandbox. -->
<!-- =================================================================== -->
<target name="create.sandbox" if="clean.build" >
<exec executable="si">
<arg line="dropsandbox" />
<arg line="--hostname=${mks.server}" />
<arg line="--port=${mks.port}" />
<arg line="--noconfirm" />
<arg line="--batch" />
<arg line='--delete=none' />
<arg line="-Y" />
<arg line="${basedir}\${prj.name}\project.pj" />
</exec>
<delete dir="${prj.name}" />
<exec executable="si" resultproperty="createSBResult">
<arg line="createsandbox" />
<arg line="--hostname=${mks.server}" />
<arg line="--port=${mks.port}" />
<arg line="--project=c:/Projects/StoreWeb2/${prj.name}/project.pj" />
<arg line="--projectRevision=${checkpoint.version}" />
<arg line="--populate" />
<arg line="--recurse" />
<arg line="-Y" />
<arg line="${basedir}\${prj.name}" />
</exec>
<!-- Check if the project is empty but for the mks system file project.pj -->
<pathconvert property="is.project.not.empty" setonempty="false">
<fileset dir="${prj.name}">
<exclude name="project.pj"/>
</fileset>
</pathconvert>
<condition property="try.mainline.storeweb">
<not>
<and>
<equals arg1="0" arg2="${createSBResult}"/>
<isset property="is.project.not.empty" />
</and>
</not>
</condition>
<antcall target="create.sandbox.mainline">
<param name="prj.name" value="${prj.name}"/>
</antcall>
</target>

Publishing ClickOnce application using NAnt and MSBuild

I'm attempting to publish a ClickOnce application using an MSBuild task within a NAnt script. The certificate is installed on the machine and I believe it's finding it, as it's now getting past an earlier problem of it not being able to get the certificate itself. However, it's now failing with the error:
[msbuild]
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(4512,5):
error MSB4044: The "SignFile" task was not given a value for the
required parameter "CertificateThumbprint"
The task currently is called like this:
<msbuild project="${SourceURL}/pathToProject/project.csproj" verbosity="Minimal">
<property name="Configuration" value="Client" />
<property name="Platform" value="AnyCPU" />
<arg value="/p:ApplicationVersion=${actualVersion}" />
<arg value="/p:CertificateThumbprint=XXX" />
<arg value="/p:ManifestCertificateThumbprint=XXX" />
<arg value="/t:publish" />
</msbuild>
How should I be passing the CertificateThumbprint into the publish task? I'm trying to avoid having to switch directly to using signtool or mage, since I'd like to keep it as close as possible to using Visual Studio directly as possible.

MSbuild 4.0 fail to compile .Net 3.5 project

I am using Msbuild 4.0.
In our project few solution are having .net 3.5 projects.
When i compile it through Visual studio it works. If i build the same using Msbuild it fails.
Following is the compilation issue:
error : Compilation failed. Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Exception from HRESULT: 0x80131515
Even i tried with changing
toolsversion to 3.5
through additionalproperties of item. [ I am using Msbuild task to build my solution]
Our Msbuild task looks like below.
<Target Name="BuildDotNETSolutions" Condition="'$(Group)' != ''" DependsOnTargets="Init;GetNextVersionNumber">
<!-- Complie solutions -->
<!-- Version property is useful for changing the Wix Msi version-->
<MSBuild Projects="#(Solution)" BuildInParallel="true"
Properties="Configuration=$(Configuration);PostbuildEvent=;Version=$(BuildNextVersionNumber)"
Condition="'%(Solution.Group)' == '$(Group)' And '%(Solution.Type)' == 'DotNET' And '%(Solution.IsRebuild)'=='$(IsRebuild)'">
<Output
TaskParameter="TargetOutputs"
ItemName="BuildOutputs" />
</MSBuild>
We are passing solutions through properties file like below
<Solution Include="$(Implementation)\MultiEvent.csproj;">
<Group>Event</Group>
<AdditionalProperties>
ReferencePath=$(Implementation)\References;
ToolsVersion=3.5;
</AdditionalProperties>
<IsRebuild>True</IsRebuild>
<Type>DotNET</Type>
</Solution>
I don't know if you happen to have any script-runner that runs MSBuild. Personnally, I'm using NAnt and everything is working fine. I've read (somewhere) that MSBuild sometimes do stupid things and by adding the property "TrackFileAccess" and set it to "false" helps a lot. In my case, it fixed the problem.
If it can be of any help, I've included my NAnt build task. I hope it can be useful to you.
<!--*******************************************************************************
Runs MSBuild to build the project solution
Arguments:
${MSBuild.exe}: Path to MSBuild.exe
${project.solution}: the solution name to build
${buildconfiguration}: The build configuration to trigger the build
${build.dir} : The directory where to put builded files
********************************************************************************-->
<target name="run.msbuild" description="Rebuilds a given solution file">
<echo message="Rebuilding Solution ${project.solution}" />
<echo>${MSBuild.exe}</echo>
<exec program="${MSBuild.exe}">
<arg value="${project.solution}"/>
<arg line="/property:SignAssembly=${project.sign},AssemblyOriginatorKeyFile=${project::get-base-directory()}\${project.signature.file}" />
<arg line="/property:OutDir=${build.dir}" />
<arg line="/property:TrackFileAccess=false" />
<arg line="/property:DebugType=${debug.type}" />
<arg line="/property:Platform="Any CPU"" />
<arg line="/nologo" />
<arg line="/verbosity:minimal" />
<arg line="/property:Configuration=${buildconfiguration}"/>
</exec>
in the case of a Development build, I set the following params :
<property name="buildconfiguration" value="Debug"/>
<property name="debug.type" value="full" />

<msbuild> task or msbuild.exe with NAnt?

It looks like there are (at least) two options for getting nant to use csproj files: using the task of NAntContrib or using msbuild.exe directly (e.g., codecampserver). Am I reading this right, and if so, what is the advantage of using msbuild.exe over the NAntContrib task?
The NAntContrib assumes .NET Framework V2.0. If you want to use .NET 3.5, you'll need to call MsBuild.exe directly. As you upgrade to new versions of .NET, you need only modify the MSBuildPath property.
Here's an example:
<property name="MSBuildPath" value="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"/>
<target name="build">
<exec program="${MSBuildPath}">
<arg line='"${SolutionFile}"' />
<arg line="/property:Configuration=${SolutionConfiguration}" />
<arg value="/target:Rebuild" />
<arg value="/verbosity:normal" />
<arg value="/nologo" />
<arg line='/logger:"C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll"'/>
</exec>
</target>
The value MSBuildPath for different versions of .NET are
2.0, 3.0 C:\Windows\Microsoft.NET\Framework64\v2.0.50727\MSBuild.exe
3.5 C:\Windows\Microsoft.NET\Framework64\v3.5\MSBuild.exe
4, 4.5.x, 4.6.x, 4.7.x C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
For a 32-bit build, change Framework64 to Framework
Update
Following up on some of the comments, the value attribute is used for parameters that have no white space characters where as line is used for parameters that contain white spaces. Otherwise, the NAnt would use the space as an end of input.
Here is a simple target
<target>
<loadtasks assembly="${nant::get-base-directory()}/../../nantcontrib-0.85/bin/NAnt.Contrib.Tasks.dll" />
<msbuild project="${filepath.root}/yourproject.csproj" verbose="true">
<arg value="/p:Platform=${build.platform}" />
<arg value="/t:Rebuild" />
<arg value="/p:OutputPath=${build.dir}/bin/" />
</msbuild>
</target>

Finding TeamCity Agent's working path for use in MSBuild script

I want to copy the output files from my build to a staging server, but I can't figure out how to find the path used by TeamCity to store the build output in from in MSBuild. Any help?
Thanks!
The $(teamcity_build_workingDir) property did it.
The best way is to upload the files to teamcity. Choose step1 (General Settings) and enter artifacts path. It should be something like /SourceOfProject/bin/releaese/*.dll.
I zip files before I upload them, because you only want to download 1 file that contains the complete build.
My build always has 2 steps in a nant - file.
Step1 - call msbuild
Step2 - use 7zip to create zip
<?xml version="1.0"?>
<project name="MyProjectBuild"
default="build" basedir="."
xmlns="http://nant.sf.net/release/0.85/nant.xsd">
<description>Build Script</description>
<target name="build" >
<exec program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" >
<arg value="MyProject\MyProject.csproj" />
<arg value="/t:Build" />
<arg value="/p:Configuration=Release" />
</exec>
<exec program="7z" >
<arg value="a" />
<arg value="MyProject\bin\release\buildresult.zip" />
<arg value="MyProject\bin\release\*.dll" />
</exec>
</target>
</project>
Anyway my working path is:
C:\Programme\TeamCity\buildAgent\work