Deploy non-Web Apps with MSDeploy

In this blog post we will deploy a console app using MSDeploy.  We use a similiar approach at EBSCO to deploy Scheduled Tasks and Windows Services. 

Step 1: Extending MSBuild

The setup for this follows the same pattern we used in the Deploying a Databased Project with MSDeploy to extend MSBuild by adding a targets file (ConsoleAppMSDeployPackage.app.targets) which is loaded by the project file. Refer to the previous post for further details.

Step 2: Creating the MSDeploy Package

In our app.targets file, we will use the MSDeploy task again by referencing Microsoft.Web.Publishing.Tasks.dll from the VisualStudio install path.


  <UsingTask TaskName=&quot;MSDeploy&quot; AssemblyFile=&quot;$(MSBuildExtensionsPath)MicrosoftVisualStudiov14.0WebMicrosoft.Web.Publishing.Tasks.dll&quot;/>

Again we will create a target named “AfterBuild” so that packaging occurs after the build completes and use the MSDeploy task to create a package using the dirPath MSDeploy provider as the source which simply copies the application files from a directory.

    <PropertyGroup>
      <FullOutputPath>$(MSBuildProjectDirectory)$(OutputPath)</FullOutputPath>
      <FullIntermediateOutputPath>$(MSBuildProjectDirectory)$(IntermediateOutputPath)</FullIntermediateOutputPath>
      <PackageFolderPath>$(FullIntermediateOutputPath)Package</PackageFolderPath>
      <PackageFilename>$(MSBuildProjectName).zip</PackageFilename>
      <PackageFullPath>$(PackageFolderPath)$(PackageFilename)</PackageFullPath>
    </PropertyGroup>
    <MSdeploy
          Verb=&quot;sync&quot;
          Source=&quot;dirPath=&amp;quot;$(FullOutputPath)&amp;quot;&quot;
          Destination=&quot;package=&amp;quot;$(PackageFullPath)&amp;quot;&quot;
          ExePath=&quot;$(_MSDeployDirPath_FullPath)&quot;
          ImportDeclareParametersItems=&quot;$(MSBuildProjectDirectory)parameters.xml&quot;
    />

Step 3: Pre/Post Sync Commands

In the case of a non-web application deployment you will likely need to also run a command before the sync, after the sync or in some cases both. So we will create a property for each to hold the MSDeploy flags for this.  MSDeploy supports running a command before and after a sync natively. 

    <PropertyGroup>
      <PreSyncCommand> -preSync:runCommand=&amp;quot;deploymentpreSync.bat&amp;quot;</PreSyncCommand>
      <PostSyncCommand> -postSync:runCommand=&amp;quot;deploymentpostSync.bat&amp;quot;</PostSyncCommand>
    </PropertyGroup>

 

Step 4: Creating a Deploy Command

Just like the database deployment we will again create a deploy command with helpful details to make it easier for another user to execute the deployment.

    <ItemGroup>
      <DeployCMDLines Include=&quot;@ECHO OFF&quot; />
      <DeployCMDLines Include=&quot;IF %22%1%22==%22%22 GOTO Readme&quot; />
      <DeployCMDLines Include=&quot;IF %22%2%22==%22%22 GOTO Readme&quot; />

      <DeployCMDLines Include=&quot;:Deploy&quot; />
      <DeployCMDLines Include=&quot;ECHO Starting deployment ...&quot; />
      <DeployCMDLines Include=&quot;@ECHO ON&quot; />
      <DeployCMDLines Include=&quot;%22$(MSDeployPath)%22 -verb:sync -source:package=$(PackageFilename) -dest:dirPath=$(TargetPath),computername=%2 -verbose$(PreSyncCommand)$(PostSyncCommand) -setParamFile:SetParameters.%1.xml %~3 %~4 %~5 %~6 %~7 %~8 %~9&quot; />
      <DeployCMDLines Include=&quot;@ECHO OFF&quot; />
      <DeployCMDLines Include=&quot;GOTO End&quot; />

      <DeployCMDLines Include=&quot;:Readme&quot; />
      <DeployCMDLines Include=&quot;ECHO.&quot; />
      <DeployCMDLines Include=&quot;ECHO Deploys application to target path using MSDeploy&quot; />
      <DeployCMDLines Include=&quot;ECHO.&quot; />
      <DeployCMDLines Include=&quot;ECHO %(DeployTypes.DeployCommandFilenameOnly) ENVIRONMENT TARGETCOMPUTER &#91;Other MSDeploy parameters (up to 8)&#93;&quot; />
      <DeployCMDLines Include=&quot;ECHO.&quot; />
      <DeployCMDLines Include=&quot;ECHO   ENVIRONMENTttThe environment to use for the SetParameters.&#91;environment&#93;.xml file.&quot; />
      <DeployCMDLines Include=&quot;ECHO   TARGETCOMPUTERttThe target computer for the deployment.&quot; />
      <DeployCMDLines Include=&quot;ECHO   MSDeploy paramsttYou may optionally add any other MSDeploy parameters to the call.  For example:&quot; />
      <DeployCMDLines Include=&quot;ECHO     -whatif&quot; />
      <DeployCMDLines Include=&quot;ECHO     -retryAttempts&quot; />
      <DeployCMDLines Include=&quot;ECHO     -verbose&quot; />
      <DeployCMDLines Include=&quot;ECHO.&quot; />
      <DeployCMDLines Include=&quot;GOTO End&quot; />

      <DeployCMDLines Include=&quot;:End&quot; />
    </ItemGroup>
    <WriteLinesToFile
      File=&quot;$(PackageFolderPath)$(MSBuildProjectName).SQL.deploy.cmd&quot;
      Lines=&quot;@(DeployCMDLines)&quot;
      Overwrite=&quot;true&quot; />

In this case we have two required parameterso on the command.  In addition to the desired configuration we also have the TARGETCOMPUTER argument to specify which server to deploy the package to.

Also notice we added the preSync and postSync commands to the MSDeploy.exe call.

The Source

A working example of this solution is on GitHub if you want to try it yourself. 

https://github.com/rschiefer/ConsoleAppMSDeployPackage

You should be able to clone the repo and build successfully without any changes. 

Feedback

Please let me know if you found this post helpful in the comments or on Twitter.  Also, leave feedback if you have a suggestion for a furture msdeployallthethings post.

1 thought on “Deploy non-Web Apps with MSDeploy”

  1. Pingback: Continuous Delivery… Incrementally – dotnet Catch

Leave a Reply