how to automated a BUILD task - visual-studio-2010

I need help about how to automated a task with MSBUILD.
I wrote a small command line program that process files and I want integrate it at the moment of BUILD the solution.
The program itself is used like this:
Processor.exe inputFile.txt outputFile.txt –p
-p of course represents some parameters.
Is there a simple way to make visual studio to run this exe AFTER each Buildup??
To be honest I research a lot about the MSBUILD, but there is so much information out there, that it overwhelmed me.

There are different solutions but in your case the best is probably with custom AfterBuild target and Exec task. You should add it to your cproj file after Microsoft.CSharp.targets get imported.
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name ="AfterBuild">
<Exec Command="Processor.exe inputFile.txt outputFile.txt –p" />
</Target>
You can read more about Exec Task here:
Exec Task

Related

How to prioritize a project in a VisualStudio-solution?

We have a solution with around 70 projects. One of them takes relatively long (~10min) but does not use system resources. We also employ parallel build to speed things up.
When I (re)add this project to the solution, it is at the end of the build order. The machine is 100% busy when compilong 69 projects and then 10min idle when compiling the 70th. When I manually edit the .sln-file so that the project comes first in all lists, it is somewhere in the middle. How can I move it to the beginning?
This is not about dependencies. This project A has only one to another project B and I am fine if B is first as long as A is second. Also, no other projects depends on project A.
It sounds like you have already tried editing project dependencies in visual studio. If you have already edited it to make the project first, but it still takes a while then you probably should just take it out of the solution file. Then put the building of it into your own msbuild script where you can use the MSBuildExtensions parallel tasks to make it build at the same time as everything else:
See https://mikefourie.wordpress.com/2012/02/29/executing-msbuild-targets-in-parallel-part-1/
And I'm pretty sure the MSBuildExtensions library is a nuget package now as well.
VisualStudios sln-files are very limited and are written in a format defined decades ago. In fact, it is converted to a msbuild-script before doing anything useful.
To have more flexibility, I added an msbuild-script (master.msbuild) with something similar to this (untested but proper documentation is available)
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectsToBuild Include="longrunningproject.proj" />
<ProjectToBuild
Include="SolutionWithTheOther69Projects.sln"
Properties="Configuration=Debug;Platform=x86"/>
</ItemGroup>
<Target Name="Build" >
<MSBuild
Projects="#(ProjectsToBuild)"
Targets="Build"
BuildInParallel="true"
ContinueOnError="false"
Properties="VeloxVersion=$(VeloxVersion);RootDir=$(RootDir)"
/>
</Target>
</Project>
Projects are executed in order they are defined. Still no control what happens in the solution but I can put projects in front or behind it and can so influence the build order.
If the long-running task is called by an msbuild-exec-task, it is important to set the YieldDuringToolExecution-flag of this task. E.g.
<Exec
Command="..."
YieldDuringToolExecution="true"
/>
Otherwise, things are starting in parallel and then slowly dying off until the exec-task is done. I could not decode the logic behind that but honestly, I do not care.
After several days of try and error, the build machine screams at 100%-cpu-load, slowly come down to the one long-running task and then is done. Speedup-factor 2.5 :D
How can I move it to the beginning?
You can create a MSBuild project file named "before.<SolutionName>.sln.targets" in the same folder as your solution.
Then build the solution with command line (Visual Studio will ignore this file.), the before.<SolutionName>.sln.targets will be built before all of the Visual Studio projects in the solution.
In this case, we just need to build that special project in the before.<SolutionName>.sln.targets file, that special project will be built before all of projects in the solution.
The content of before.<SolutionName>.sln.targets like:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="BuildSpecialProject" BeforeTargets="Build">
<Message Text="Build My Specify Project" />
<MSBuild Projects="Path\YouSpecialName.csproj"/>
</Target>
</Project>
Then build the solution file with command line with MSBuild or dotnet:
msbuild /t:build "<SolutionPath>\<SolutionName>.sln"
dotnet build "<SolutionPath>\<SolutionName>.sln"
Check this thread for some more details.
Hope this helps.

Running test case files(tst) as part of MSbuild

I am using TFS 2010 and Visual Studio 2010. I have a build definition which points to my solution. The build runs overnight
I have a set of test case files(*.tst) and i would like my current build to include these as part of the build and to execute them overnight. The test case files are in source control
I read that i have to use MsTest.exe but unsure how to get started?
Can anyone point me please how i can get started on running the test case files as part of the build? Any examples please?
Thanks in advance,
There are several ways you can have your test cases run. One way is to add an invoke process or Exec Command to your build project file or workflow.
Place the call to mstest in the AfterBuild target or workflow step. The other way would be to separate out the build and test cases into different builds.
Here are a couple of links to get you started:
How to: Configure and Run Scheduled Tests After Building Your Application
Example of MSBuild with MSTest
*Based on your comments here is an update of something you can do to get more information about the error or to continue if you encounter an error. You do not need to check for the error code if you just want to stop on any error but if you do want to check the error code then you would do something like this:
<Target Name="AfterBuild">
<Message Text="Running tests..." />
<PropertyGroup Label="TestSuccessOrNot">
<TestSuccessOrNot>5</TestSuccessOrNot>
</PropertyGroup>
<!-- Run MSTest exe-->
<Exec Command="cd ." IgnoreExitCode="False" ContinueOnError="ErrorAndContinue">
<Output TaskParameter="ExitCode" PropertyName="TestSuccessOrNot" />
</Exec>
<Message Text="ExitCode = $(TestSuccessOrNot)" />
<Error Condition="'$(TestSuccessOrNot)' != '0'" Text="Unit tests fail!" /> </Target>

How to execute Oracle utility in MSBuild

I want to execute the oracle's import utility in MSBuild as a task. Please give a detailed answer. I am a beginner.
You may want to look into the MSBuild Exec task. I am not familiar with the Oracle utility you specified, but I do know that the Exec task will run most anything that can be run from a command line. The relevant MSBuild configuration you would need might looks something like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="DoImport">
<Exec
Command="imp SYSTEM/password FILE=dba.dmp FROMUSER=scott TABLES=(dept,emp)" />
</Target>
</Project>
A somewhat more long-winded but better solution is to develop a custom Task that extends the ToolTask base class. This will allow better logging and you can define the arguments by using specific XML attributes.
I've developed one for SqlPlus and it works really well.

How do I tell MSTEST to run all test projects in a Solution?

I need to know how to tell MSTEST to run all test projects in a solution file. This needs to be done from the command line. Right now I have to pass it a specific project file, I'm trying to get it to run from a SOLUTION file.
I'm hoping this is possible, because in Visual Studio, hitting Ctrl+R, A, runs ALL tests in the currently opened solution.
The way I've interpretted the help files, you have to pass in each DLL specifically.
I want to run this from the command line from my CruiseControl.NET server, so I can write other utilities to make this happen. If there is a wierd way of getting this to happen through some OTHER method, let me know.
How do I tell MSTEST to run all test projects for a solution?
<exec>
<!--MSTEST seems to want me to specify the projects to test -->
<!--I should be able to tell it a SOLUTION to test!-->
<executable>mstest.exe</executable>
<baseDirectory>C:\projects\mysolution\</baseDirectory>
<buildArgs>/testcontainer:testproject1\bin\release\TestProject1.dll
/runconfig:localtestrun.Testrunconfig
/resultsfile:C:\Results\testproject1.results.trx</buildArgs>
<buildTimeoutSeconds>600</buildTimeoutSeconds>
</exec>
To elaborate on VladV's answer and make things a bit more concrete, following the suggested naming convention running your tests can be easily be automated with MSBuild. The following snippet from the msbuild file of my current project does exactly what you asked.
<Target Name="GetTestAssemblies">
<CreateItem
Include="$(WorkingDir)\unittest\**\bin\$(Configuration)\**\*Test*.dll"
AdditionalMetadata="TestContainerPrefix=/testcontainer:">
<Output
TaskParameter="Include"
ItemName="TestAssemblies"/>
</CreateItem>
</Target>
<!-- Unit Test -->
<Target Name="Test" DependsOnTargets="GetTestAssemblies">
<Message Text="Normal Test"/>
<Exec
WorkingDirectory="$(WorkingDir)\unittest"
Command="MsTest.exe #(TestAssemblies->'%(TestContainerPrefix)%(FullPath)',' ') /noisolation /resultsfile:$(MSTestResultsFile)"/>
<Message Text="Normal Test Done"/>
</Target>
Furthermore integrating MsBuild with CruiseControl is a piece of cake.
Edit
Here's how you can 'call' msbuild from your ccnet.config.
First if you do not already use MSBuild for your build automation add the following xml around the snippet presented earlier:
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
..... <insert snippet here> .....
</Project>
Save this in e.g. RunTests.proj next to your solution in your source tree. Now you can modify the bit of ccnet.config above to the following:
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
<workingDirectory>C:\projects\mysolution\</workingDirectory>
<baseDirectory>C:\projects\mysolution\</baseDirectory>
<projectFile>RunTests.proj</projectFile>
<targets>Test</targets>
<timeout>600</timeout>
<logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
This is an old thread, but I have been struggling with the same issue and I realized that you can really just run MSTest on every dll in the whole solution and it doesn't really cause any problems. MSTest is looking for methods in the assemblies marked with the [TestMethod] attribute, and assemblies that aren't "test" assemblies just won't have any methods decorated with that attribute. So you get a "No tests to execute." message back and no harm done.
So for example in NAnt you can do this:
<target name="default">
<foreach item="File" property="filename">
<in>
<items>
<include name="**\bin\Release\*.dll" />
</items>
</in>
<do>
<echo message="${filename}" />
<exec program="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe">
<arg value="/testcontainer: ${filename}" />
<arg value="/nologo" />
</exec>
</do>
</foreach>
</target>
and it will run all the test methods in every dll in every bin\Release folder in the solution. Those which are not test dlls will return a "No tests to execute." and those that have tests will have the tests run. The only part I haven't figured out yet is that (in NAnt) execution stops the first time a command returns a non-zero value. So if any unit tests fail it doesn't keep going to execute any tests in subsequent assemblies. That is not great, but if all the tests pass, then they will all run.
I just resolve this problem recently. Here is my proposal: Use testmetadata + testlist option of mstest
First you should create a testlist in testmetadata file(vsmdi)
the commandline should be mstest /testmetadata:....vsmdi /testlist:<name>
Then use ccnet config to run mstest
i know this thread is quite Old, but its still high on Google so i thought i might help one or two.
Anyway, since there is no satisfactory solution for this.
I've written an msbuild task for this.
details can be found here:
http://imistaken.blogspot.com/2010/08/running-all-tests-in-solution.html
You could enforce some convention on the naming and location of test projects, then you could run MSTest on, say, all *Test.dll below the location of your solution.
As far as I know, there is no way to tell a test project from a 'normal' DLL project based soleley on a solution file. So, an alternative could be to analyze the project files and/or .vsmdi files to find the test projects, but that could be rather tricky.
I don't know directly but this is where VSMDI [fx:spits in a corner] can help. In your solution add all the tests to the VSMDI. And then pass the VSMDI to mstest using /testmetadata.
However I would suggest that you follow the conventions above. And use a naming convention and dump that out from the SLN file using say a for loop in the command script
I would just write a target that calls it the way you want, then whip up a batch file that calls the target that contains all the DLL's to be tested.
Unless you're adding test projects all the time, you'll very rarely need to modify it.
Why not just have msbuild output all the test assemblies to a folder.
Try setting OutputPath,OutputDir,OutDir properties in msbuild to accomplish this.
then have mstest execute against all assemblies in that folder.

Calling batch/script files from VC6/VC2005/VC2008 project files

Is there a way to invoke an external script or batch file from VC6 (and later) project files?
I have a background process that I need to kill before attempting to build certain projects (DLLS, executables) and haven't found a way to successfully do so from the project itself. I'd like simply to call a batch file with a taskkill command in it.
(Yes, I could run the batch file from a command line before building the projects, but I don't always remember to do so and having it done automatically would be more convenient and less irritating for the whole development team.)
You can create a utility project (configuration type: Utility in the project property pages) that has a post build event. You then call the batch file from that Post-Build event. If I remember correctly, utility configuration appeared in VS2005. But I believe the same can be achieved with another type of configuration on VC6.
Here is an example of a setup (this is the text of the Command Line property of the Post-Build Event):
set solutionDir=$(SolutionDir)
set platformName=$(PlatformName)
set configurationName=$(ConfigurationName)
call $(SolutionDir)PostBuild.bat
As you can see, you have all the flexibility of customizing the batch environment based on VisualStudio macros.
If you want to have this batch file called every time you build, add a dependency to the requiring project (your main executable or dll project for example). You can add your batch file to the solution items for convenient access (right-click on the solution and select Add -> Existing Item...).
You can even invoke the build command on this utility project to force the execution of the batch file.
At work we have a similar setup to start our unit tests each time a build is triggered.
You could invoke it from a custom build step or a build event.
At least for C# in Visual Studio 2008, you can open the project file and find within the file the following comment:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
Uncomment the one that works best for you, in this case the "BeforeBuild" item. Then substitute your batch file for the one I have here:
<Target Name="BeforeBuild">
<Exec Command="MyBatchFile.bat" />
</Target>
That's all there is to it; whenever you build that project, this will take place each and every time.
That said, I do not know if this works the same for VS 2005 or, especially, VC6. YMMV!

Resources