4

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?

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
John Saunders
  • 160,644
  • 26
  • 247
  • 397

1 Answers1

4

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.

alex.b
  • 4,547
  • 1
  • 31
  • 52
  • I agree that this turned out not to be a good idea in general. It was expedient because it meant that all components of the application could be deployed via MSDEPLOY, into all environments. It was part of getting rid of MSI installers for the console applications. The MSI installers did nothing other than copy files. – John Saunders Apr 30 '14 at 19:29
  • Also, I've tried to work on setting ACL's, faced with error with message `ERROR_SITE_DOES_NOT_EXIST`, found [SO topic](https://stackoverflow.com/questions/6861990/can-web-deploys-setacl-provider-be-used-on-a-sub-directory) with similar problem with comment `This doesn't seem to work for applications that are not pushed into a virtual directory and are pushed to Default Site/ for instanc` ... So I think setting ACLs won't work for you. It's better to go with MSI/Wix. – alex.b May 01 '14 at 03:41
  • True, but Setup projects are not supported in VS2012/2013, and Wix or even InstallShield have a big learning curve. MSDEPLOY "worked", with my only issues being those above. Thanks for the answer. – John Saunders May 01 '14 at 04:03