Wait for an Exec task to finish - msbuild

One of my msbuild targets works as following:
get configuration files
start window service with those configuration files
exec service specific task
stop window service
repeat
The issue is that sometimes service stop executable task (Exec Command="sc stop myservice") takes longer time and when "sc start myservice" is called it says that service is already running. So my question is: how can I wait for "exec" command ot finish? I tried to put each executable in target and call with "CallTarget" and putting appropriate "DependsOnTargets" or "AfterTargets" and it didn't work. Can you help me? Thanks in advance.

The problem was that Exec actually did finished command execution (he simply thrown "sc stop myservice") and after that another exec started to work. I added timeout for the "sc start myservice" for a minute and it solved. The result looked like:
<Exec Command="sc stop myservice" ContinueOnError="true" />
<Exec Command="sc start myservice" ContinueOnError="true" Timeout="60000" />

Related

MSBuild - MsBuildExtensionPack starting windows service with delay

I am using MSBuild task to start a windows service. I am using following code:
MSBuild.ExtensionPack.Computer.WindowsService TaskAction="Start" ServiceName="AppServices" ContinueOnError='false'/>
If I start the service I am getting following error:
Start Service failed with return code '[7] ServiceRequestTimeout'
Is there any setting or option to tell MSBuild to start service after waiting for a minute or two. Or Is there any way to introduce delay before calling this task within MSBuild?
Thanks
I do not think there is a way to tell the actually WindowsService task to delay the command. You can try putting this before your call though though:
<MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="1000"/>
This will put the executing thread to sleep for the timeout specified (in milliseconds).

How can I remotely start/stop a service using MSBuild?

I'd like to remotely start or stop a windows service on another machine using MSBuild. To accomplish this, I wrote this script:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="C:\Program Files (x86)\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<Target Name="MyTarget">
<ServiceController MachineName="Box2" ServiceName="MyService" Action="Stop" />
</Target>
</Project>
When I run that on a machine that can see Box2, I get this:
Project
"C:\Scripts\Test.xml" on node 1 (default
targets).
C:\Scripts\Test.xml(4,5): error : Couldn't
find the 'MyService'
service on 'Box2' Done Building
Project
"C:\Scripts\Test.xml" (default targets) --
FAILED.
I know that I have the service name correct (I copied and pasted it from the actual service list), and I'm pretty sure that it can see Box2 because if I change it to a machine name that doesn't exist (e.g. Box2asdf), it takes about 10 seconds to come back (with the exact same error, mind you), as opposed to the nearly immediate response that I get when I provide the correct machine name.
How might I debug this issue?
You might try this instead...
You can use the command line program sc and execute that...
ie
SC \ServerName stop ServiceName
http://support.microsoft.com/kb/166819
For more information on how to execute a command from msbuild check this out..
execute a command with parameters using msbuild
The community tasks should work. Just use Sc query to check that the service does work. as for using msbuild its still using msbuild if you wrap sc in an exec?
At least you dont have a dependency on a third party dll in your build process.
ServiceController Target internally uses ServiceController Class. But it doesn't return the reason why it couldn't find the service. If you are shure that both computer and service names are correct, the next thing I can suggest to analyze is access violation problems.
And #jsobo's answer can be very useful to diagnose the actual reason because it can show native errors without .Net exception wrappers around them:
sc.exe \Box2 stop MyService

CruiseControl.Net and NUnit - tests finish, but task doesn't?

I've got a CruiseControl.Net setup using Nant to clean the previous logs, and then it kicks off a msbuild of a VS project, finally running nunit-console to execute the tests.
It seems to build for a few seconds (fine) and then hops on to running the 600 tests, which takes about a minute. However even though the log files are there, it sits there doing 'nothing' for 10 minutes, at which point the built times out and the process exits. The CruiseControl.NET webpage then shows the result as failed, with an exception:
ThoughtWorks.CruiseControl.Core.Tasks.BuilderException: Command Line Build timed out (after 600 seconds)
at ThoughtWorks.CruiseControl.Core.Tasks.ExecutableTask.Execute(IIntegrationResult result)
at ThoughtWorks.CruiseControl.Core.Tasks.TaskBase.Run(IIntegrationResult result)
at ThoughtWorks.CruiseControl.Core.Project.RunTask(ITask task, IIntegrationResult result, Boolean isPublisher)
at ThoughtWorks.CruiseControl.Core.Project.RunTasks(IIntegrationResult result, IList tasksToRun, Dictionary`2 parameterValues)
at ThoughtWorks.CruiseControl.Core.Project.Run(IIntegrationResult result)
at ThoughtWorks.CruiseControl.Core.IntegrationRunner.Build(IIntegrationResult result)
at ThoughtWorks.CruiseControl.Core.IntegrationRunner.Integrate(IntegrationRequest request) BaseDirectory: , Executable: C:\Program Files\NUnit 2.5.8\bin\net-2.0\nunit-console.exe
The ccnet.config script is below. I've tried changing the timeout to 3 minutes just in case that was something to do with it, but even if that did work (it didn't) it's a dodgy hack, as by rights when the tests are finished running, they should exit gracefully!
I've run the command at the commandline and confirmed it only takes about a minute to run. Any theories?
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project name="CodeTests">
<workingDirectory>C:\Source\Wholesale\Comp.EventControl.TestingFramework\</workingDirectory>
<artifactDirectory>C:\Source\Wholesale\Comp.EventControl.TestingFramework\</artifactDirectory>
<prebuild>
<!-- clean nunit output to avoid CCNET reporting
about previous build tests if current build fails -->
<nant>
<executable>C:\Nant\bin\nant.exe
</executable>
<baseDirectory>C:\Source\Wholesale\Comp.EventControl.TestingFramework</baseDirectory>
<nologo>false</nologo>
<buildFile>nant.build</buildFile>
<targetList>
<target>cleanNunit</target>
</targetList>
</nant>
</prebuild>
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
</executable>
<workingDirectory>C:\Source\Wholesale\Comp.EventControl.TestingFramework\CodeReboot
</workingDirectory>
<projectFile>CodeReboot.sln</projectFile >
<buildArgs>/noconsolelogger
/v:quiet
/noconlog
/p:Configuration=Debug
/p:ReferencePath="C:\Program Files\NUnit 2.5.8\bin;C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
/p:AdditionalReferencePath="C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
</buildArgs>
<targets>ReBuild</targets >
<timeout>180</timeout >
<logger>c:\Program Files\CruiseControl.NET\server\Rodemeyer.MsBuildToCCNet.dll</logger>
</msbuild>
<exec>
<executable>C:\Program Files\NUnit 2.5.8\bin\net-2.0\nunit-console.exe
</executable >
<buildArgs>/xml:C:\Source\Wholesale\Comp.EventControl.TestingFramework\nunit-results.xml
/nologo C:\Source\Wholesale\Comp.EventControl.TestingFramework\CodeReboot\CodeReboot\bin\Debug\CodeReboot.dll
</buildArgs>
</exec>
</tasks>
<publishers>
<merge>
<files>
<file>C:\Source\Wholesale\Comp.EventControl.TestingFramework\nunit-results.xml
</file>
</files>
</merge>
<xmllogger />
<statistics />
<artifactcleanup cleanUpMethod="KeepLastXBuilds"
cleanUpValue="20" />
</publishers>
</project>
</cruisecontrol>
What version of nunit are you using? There were some problems in the 2.5.7/2.5.8 version that causes nunit-agent to hang at the end of a test. I had this problem and reverted back to an older version of nunit and the hang problem went away. In the release notes for 2.5.9 they show that "602761 nunit-agent hangs after tests complete" has been fixed. I have not upgraded to 2.5.9 yet but that may fix your problem.
The first thing you should do try and replicate the problem locally. Do your tests run properly and exit cleanly? Run them locally and see if the nunit process hangs around.
If your tests run fine locally, try and figure out which test the build server is stalling on or whether it is completing all of the tests. If your build scripts cannot be run locally, it's a bit harder to diagnose.
Back in the day when our tests were riddled with threaded code, it was nearly always the case that a test (or the code under test) was creating threads and then failing to shut them down, causing NUnit to hang around. Threading issues are irritating because they're non-deterministic may only be visible when run on machines with more cores (like .. build servers).
If you have tests with threading / external dependencies, I'd try disabling those first (the fact that 600 tests takes a minute to run indicates that external dependencies and/or threading is involved, as a unit test usually takes ~1ms to run).

nant vs. msbuild: stopping a service

I'm trying to decide which side I'm on in the MsBuild vs. Nant war. I'm starting with: stop a service, deploy some files, restart the service. Just from looking at these two links, that is much easier to do in Nant.
MSBuild: Example of using Service Exists MSBuild task in Microsoft.Sdc.Tasks?
<target name="service_exists">
<script language="C#">
<references>
<include name="System.ServiceProcess.dll" />
</references>
<code><![CDATA[
public static void ScriptMain(Project project) {
String serviceName = project.Properties["service.name"];
project.Properties["service.exists"] = "false";
project.Properties["service.running"] = "false";
System.ServiceProcess.ServiceController[] scServices;
scServices = System.ServiceProcess.ServiceController.GetServices();
foreach (System.ServiceProcess.ServiceController scTemp in scServices)
{
etc...
Nant: http://ryepup.unwashedmeme.com/blog/2007/01/04/restart-a-windows-service-remotely/
<!-- Send the stop request -->
<exec program="sc.exe">
<arg line="\\server stop shibd_Default"/>
</exec>
<!-- Sleep a little bit, to give the service a chance to stop -->
<sleep seconds="5"/>
<!-- Send the start request -->
<exec program="sc.exe">
<arg line="\\server start shibd_Default"/>
</exec>
I wonder if the SO community agrees with me. Is it much easier to get basic things like this done in Nant? Sure looks that way. C# code in a CDATA block? WTF?
Our current build process is a) lots of bat files b) lots of cursing. I'd really like to find a good replacement, but that MsBuild stuff looks like a world of pain to my eyes. I'm thinking the way to go is to build scripts in Nant, then use MsBuild to do any .NET builds that need to be done.
One important question: which one is better at catching errors in the script before the script is run? I was thinking of rolling my own here and that was very important part of it: line up all your data and make sure that it makes sense before attempting to run.
In msbuild you could also use the ServiceController task that is packaged in the msbuild community tasks.
You can execute sc.exe using MSBuild every bit as easily ...
<Exec Command="sc.exe \\server stop shibd_Default" />
By default this will "fail" if the exit code (of sc.exe) is non-zero, but that can be customized.
With Nant, there are 2 other ways to stop a service, and one is able to track an error.
First one (using Net Stop):
<exec program="net" failonerror="false"><arg value="stop"/><arg value="${serviceName}"/></exec>
Second one (much cleaner):
<servicecontroller action="Stop" service="${serviceName}" if="${service::is-installed(serviceName,'.') and service::is-running(serviceName,'.')}" />
Note that the second line verifies that the service already exists and is running, which allows to track any weird error.
In addition to #nulpptr's answer for MSBuild, if you don't have the option of using the community tasks, you might have to resort to a hack to wait for your service to stop before moving on. If you have the resource kit you can use the EXEC task with the sleep command.
No resource kit? Use the ping trick...
However, if you don't have the resource kit, you can use the ping trick to force a delay. For instance, the following will stop your service using the sc command, and then pause for about 5 seconds:
<Exec Command="sc.exe \\server stop shibd_Default" ContinueOnError="true" />
<Exec Command="ping 127.0.0.1 -n 5 > nul" ContinueOnError="true" />

Process timeout without showing any error in test execution using cc.net

nunit tests fails when run through cc.net saying process timeout. Process has been killed
All works fine when through nUNit or VS.
Also cc.net will then show the results of previous build even if the build is a clean one.
Any help plz.
The default timeout is 600 seconds. If your tests start to exceed that the build will fail with no indication. You may need to up the timeouts for your cc.net nunit task
If you are seeing the results from a previous build, it is probably because you are not deleting the results from your previous build.
For example, my NUnit test results are written to files with the name {foo}-results.xml:
<publishers>
<merge>
<files>
<file>bin\debug\*-results.xml</file>
</files>
</merge>
</publishers>
In my tasks, I have a step in my build file that deletes the entire "bin\debug" directory so that my results are always the current ones.
One possibility is that you have a permission issue. CruiseControl is perhaps running under a service account and has different permissions than your user account (which I'm assuming you use to manually run the tests.) Try logging into the machine as the service account, then see if you can run the unit tests through VS or NUnit.
I've seen this happen if a test has an assertion, e.g. Debug.Assert(something here). When this happens to me in CC.Net, the CC.Net build pops up a message box for the assertion. Since no one closes out the message box on the build server, the NUnit test times out.