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 us开发者_Go百科e 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" />
精彩评论