Question

I want to deploy windows services from our build server running team city to windows server 2012 with minimum server-configuration.

What is one of the best ways to do this?

Was it helpful?

Solution

I usually use straight powershell or msbuild for this. I try to avoid the flaky msdeploy. In msbuild you can use the very handy msbuild extension pack thus, so assuming you can copy files to your target destination (Robocopy is handy for that) this will do the rest:

<Project ToolsVersion="4.0" DefaultTargets="InstallService" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask AssemblyFile="..\packages\MSBuild.Extension.Pack.1.2.0\lib\net40\MSBuild.ExtensionPack.dll"
TaskName="MSBuild.ExtensionPack.Computer.WindowsService"/>

  <PropertyGroup>
    <MachineName Condition="$(MachineName)==''"></MachineName>
    <ServiceName Condition="$(ServiceName)==''"></ServiceName>
    <ServicePath Condition="$(ServicePath)==''"></ServicePath>
    <User Condition="$(User)==''"></User>
    <Password Condition="$(Password)==''"></Password>
    <SuppressStart Condition="$(SuppressStart)==''"></SuppressStart>
  </PropertyGroup>

  <Target Name="CheckProperties" BeforeTargets="StopService">
    <Message Text="MachineName: $(MachineName)"/>
    <Message Text="ServiceName: $(ServiceName)"/>
    <Message Text="ServicePath: $(ServicePath)"/>
    <Message Text="User : $(User)"/>
    <Message Text="SuppressStart : $(SuppressStart)"/>
  </Target>

  <Target Name="StopService" BeforeTargets="InstallService">

    <MSBuild.ExtensionPack.Computer.WindowsService
      TaskAction="CheckExists"
      ServiceName="$(ServiceName)"
      MachineName="$(MachineName)">
      <Output TaskParameter="Exists" PropertyName="DoesExist"/>
    </MSBuild.ExtensionPack.Computer.WindowsService>

    <MSBuild.ExtensionPack.Computer.WindowsService
      TaskAction="Stop"
      ServiceName="$(ServiceName)"
      MachineName="$(MachineName)"
      Condition="$(DoesExist)=='True'">
    </MSBuild.ExtensionPack.Computer.WindowsService>
  </Target>

  <Target Name="StartService" AfterTargets="InstallService">

    <MSBuild.ExtensionPack.Computer.WindowsService
    TaskAction="CheckExists"
    ServiceName="$(ServiceName)"
    MachineName="$(MachineName)">
      <Output TaskParameter="Exists" PropertyName="DoesExist"/>

    </MSBuild.ExtensionPack.Computer.WindowsService>

    <MSBuild.ExtensionPack.Computer.WindowsService
      TaskAction="Start"
      ServiceName="$(ServiceName)"
      MachineName="$(MachineName)"
      Condition="$(DoesExist)=='True' And $(SuppressStart)=='False'"
      RetryAttempts="20">
    </MSBuild.ExtensionPack.Computer.WindowsService>
    <Message Text="Service $(ServiceName) set not to start" Condition="$(SuppressStart)=='True'" Importance="High" />
  </Target>

  <Target Name="InstallService">

    <PropertyGroup>
      <ServiceExeExists Condition="Exists('$(ServicePath)')">True</ServiceExeExists>
    </PropertyGroup>

    <Message Text="Installing $(ServicePath) %(ServiceName.Identity)" Importance="high"/>
    <MSBuild.ExtensionPack.Computer.WindowsService
      TaskAction="CheckExists"
      ServiceName="$(ServiceName)"
      MachineName="$(MachineName)">
      <Output TaskParameter="Exists" PropertyName="DoesExist"/>

    </MSBuild.ExtensionPack.Computer.WindowsService>

    <Message Text="Installed $(ServiceName) $(ServicePath) for $(User) and $(Password)" Importance="high"/>
    <MSBuild.ExtensionPack.Computer.WindowsService
      TaskAction="Install"
      ServiceName="$(ServiceName)"
      User="$(User)"
      Password="$(Password)"
      ServicePath="$(ServicePath)"
      MachineName="$(MachineName)"
      Condition="!$(DoesExist)"/>

    <MSBuild.ExtensionPack.Computer.WindowsService
      TaskAction="SetAutomatic"
      ServiceName="$(ServiceName)"
      MachineName="$(MachineName)"
      Condition="!$(DoesExist)"/>
    <Warning Text="%(ServiceName.Identity) service already exists" Condition="$(DoesExist)"/>

  </Target>

</Project>

OTHER TIPS

We are using the msdeploy package defined like this:

<sitemanifest>
  <runCommand path='presync.cmd' waitInterval='30000'/>
  <dirPath path='$winSvc' />
  <runCommand path='postsync.cmd' waitInterval='30000'/>
</sitemanifest>

the presync.cmd:

net stop Svc
installUtil /u /name=Svc $destPath\Svc.exe

the postsync.cmd:

installUtil /name=Svc $destPath\Svc.exe
net start Svc

All files are generated by powershell script.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top