console-applicationmsdeploywebdeploymsbuild-wpp

How to use the Web Publishing Pipeline and Web Deploy (MSDEPLOY) to Publish a Console Application?


I would like to use web deploy to publish a Visual Studio "Console" application to a folder on the target system.

I have had some luck, and have been able to produce something similar to what I need, but not quite.

I've added the following to the console .csproj:

added the following projectName.wpp.targets file

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

and I've added the following projectName.wpp.targets:

<Project DefaultTargets="Build"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">

  <PropertyGroup>
    <DeployAsIisApp>false</DeployAsIisApp>
    <IncludeSetAclProviderOnDestination>false</IncludeSetAclProviderOnDestination>
  </PropertyGroup>
  <ItemGroup>
    <FilesForPackagingFromProject Include="$(IntermediateOutputPath)$(TargetFileName).config">
      <DestinationRelativePath>bin\%(RecursiveDir)%(FileName)%(Extension)</DestinationRelativePath>
      <FromTarget>projectName.wpp.targets</FromTarget>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Project>

I then edit the .SetParameters.xml file as follows:

<parameters>
  <setParameter name="IIS Web Application Name" value="c:\company\project" />
</parameters>

When I then deploy using the generated .cmd file, I get all the files deployed to C:\company\project\bin.

That's not bad, but I'd like to do better. In particular, I'd like to omit the "bin" folder and put all files in the "C:\company\project" folder, and I'd like to be able to specify the ACLs

Has anybody been able to work around these problems?


Solution

  • Ok, so here's the way how to omit the 'bin' folder.
    First of all, I'd like to emphasize that all this msdeploy-related stuff is for web apps deployment, and 'bin' folder seems for me to be almost hardcoded deeply inside. So if you want to get rid of it - you have to do some dirty things. Which I did.

    We'll have to change $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets project a little bit, so it's better to change not it, but it's copy.

    Steps:

    1.Backup $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets(alternatively, you could install MSBuild.Microsoft.VisualStudio.Web.targets package, redirect your csproj file to Microsoft.WebApplication.targets file obtained from package and work with it).
    2. In the $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplicaton.targets find the xml node which looks like <CopyPipelineFiles PipelineItems="@(FilesForPackagingFromProject)"(there are several ones of them, take the one from the line ~2570).
    3. Comment the node out, replace with the custom one, so eventually it will look like:

    <!--
    <CopyPipelineFiles PipelineItems="@(FilesForPackagingFromProject)"
                           SourceDirectory="$(WebPublishPipelineProjectDirectory)"
                           TargetDirectory="$(WPPAllFilesInSingleFolder)"
                           SkipMetadataExcludeTrueItems="True"
                           UpdateItemSpec="True"
                           DeleteItemsMarkAsExcludeTrue ="True"
                       Condition="'@(FilesForPackagingFromProject)' != ''">
      <Output TaskParameter="ResultPipelineItems" ItemName="_FilesForPackagingFromProjectTempory"/>
    </CopyPipelineFiles>-->
    
    <!-- Copying files to package folder in 'custom'(dirty) way -->
    <CreateItem Include="$(OutputPath)\**\*.*">
      <Output TaskParameter="Include" ItemName="YourFilesToCopy" />
    </CreateItem>
    <Copy SourceFiles="@(YourFilesToCopy)"
          DestinationFiles="@(YourFilesToCopy->'$(WPPAllFilesInSingleFolder)\%(RecursiveDir)%(Filename)%(Extension)')" />
    

    Then
    4. Your projectName.wpp.targets don't have to have FilesForPackagingFromProject, so it will look like:

    <!-- targets -->
        <PropertyGroup>
          <DeployAsIisApp>false</DeployAsIisApp>
          <IncludeSetAclProviderOnDestination>false</IncludeSetAclProviderOnDestination>
        </PropertyGroup>
        <ItemGroup>
        <!-- intentionally left blank -->
        </ItemGroup>
        </Project>
    

    That's it. Worked for me(tm), tested. Let me be honest, I don't like this approach, but that was the only way I made it working in the needed way. It's up to you whether you'll use it in your project or not.

    My opinion is not to use msdeploy here - it was not for you task.
    Better to write msbuild-scripts from scratch or accept the 'bin' folder, and fight against the framework again once next customization is required.