views:

419

answers:

3

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: http://stackoverflow.com/questions/173393/example-of-using-service-exists-msbuild-task-in-microsoft-sdc-tasks/173440#173440

<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.

+4  A: 

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.

nullptr
Can you then wrap that Exec in a foreach? Maybe that's the reason for the weird command script in my post?
jcollum
MSBuild doesn't really have a foreach, because it's declarative, not imperative. You'd need to do something like `<Exec Command="sc \\server stop %(ServiceName.Identity)" />` where you've got an `<ItemGroup><ServiceName Include="service1;service2;service3" />`...
Roger Lipscombe
+5  A: 

In msbuild you could also use the ServiceController task that is packaged in the msbuild community tasks.

mockedobject
+1  A: 

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.

jcmeyrignac