How to get Visual Studio 'Publish' functionality to include files from post build event?
Asked Answered
W

7

96

I am currently attempting to use Visual Studio 2010 'Publish' and MSDeploy functionality to handle my web deployment needs but have run into a roadblock with regards to customizing the package depending on my build configuration.

I develop in a 32bit environment but need to create a release package for a 64bit environment, so in the 'Release' configuration I have a post build event that copies the 64bit version of a third-party dll into the bin directory overwriting the 32bit version. When I use the 'Publish' functionality, even though the correct 64bit dll is being copied to the bin directory, it doesn't get included in the package.

Is there a way to get the 'Publish' to include files that have been copied into the bin directory during a post build event?

Wellmeaning answered 29/6, 2010 at 4:34 Comment(2)
If you use a pre-build event instead, this seems to work as you'd like already (Visual Studio 2013, ASP.NET project template).Womanlike
They appear to have removed the pre-built behavior mentioned in the comment above in Visual Studio 2015 and later.Io
S
97

I answered a similar but different question at How do you include additional files using VS2010 web deployment packages?.

In your scenario you are using post build event, I would recommend dropping the post build event and implement your actions using your own MSBuild targets instead of post build event. Below you'll find the text of the other answer.


From: How do you include additional files using VS2010 web deployment packages?


Great question. I just posted a very detailed blog entry about this at Web Deployment Tool (MSDeploy) : Build Package including extra files or excluding specific files.

Here is the synopsis. After including files, I show how to exclude files as well.

Including Extra Files

Including extra files into the package is a bit harder but still no bigee if you are comfortable with MSBuild, and if you are not then read this. In order to do this we need to hook into the part of the process that collects the files for packaging. The target we need to extend is called CopyAllFilesToSingleFolder. This target has a dependency property, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, that we can tap into and inject our own target. So we will create a target named CustomCollectFiles and inject that into the process. We achieve this with the following (remember after the import statement).

<PropertyGroup>
  <CopyAllFilesToSingleFolderForPackageDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>

This will add our target to the process, now we need to define the target itself. Let’s assume that you have a folder named Extra Files that sits 1 level above your web project. You want to include all of those files. Here is the CustomCollectFiles target and we discuss after that.

<Target Name="CustomCollectFiles">
  <ItemGroup>
    <_CustomFiles Include="..\Extra Files\**\*" />

    <FilesForPackagingFromProject  Include="%(_CustomFiles.Identity)">
      <DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>

Here what I did was create the item _CustomFiles and in the Include attribute told it to pick up all the files in that folder and any folder underneath it. Then I use this item to populate the FilesForPackagingFromProject item. This is the item that MSDeploy actually uses to add extra files. Also notice that I declared the metadata DestinationRelativePath value. This will determine the relative path that it will be placed in the package. I used the statement Extra Files%(RecursiveDir)%(Filename)%(Extension) here. What that is saying is to place it in the same relative location in the package as it is under the Extra Files folder.

Excluding files

If you open the project file of a web application created with VS 2010 towards the bottom of it you will find a line with.

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

BTW you can open the project file inside of VS. Right click on the project pick Unload Project. Then right click on the unloaded project and select Edit Project.

This statement will include all the targets and tasks that we need. Most of our customizations should be after that import, if you are not sure put if after! So if you have files to exclude there is an item name, ExcludeFromPackageFiles, that can be used to do so. For example let’s say that you have file named Sample.Debug.js which included in your web application but you want that file to be excluded from the created packages. You can place the snippet below after that import statement.

<ItemGroup>
  <ExcludeFromPackageFiles Include="Sample.Debug.xml">
    <FromTarget>Project</FromTarget>
  </ExcludeFromPackageFiles>
</ItemGroup>

By declaring populating this item the files will automatically be excluded. Note the usage of the FromTarget metadata here. I will not get into that here, but you should know to always specify that.

Soledadsolely answered 30/6, 2010 at 0:31 Comment(14)
Thanks Sayed, although it's not the most straight forward method I guess this is how it's done.Wellmeaning
@Sayed what do you think about this solution I came up with? https://mcmap.net/q/219401/-why-doesn-39-t-clickonce-in-visual-studio-deploy-content-files-from-dependent-assembliesFranchescafranchise
@Sayed, this doesn't appear to work for VS2012, do you know how this can be updated for this scenario. changing to v11.0 does not work. TIA.Kickback
I believe the more natural requirement for the publishing scenario is to emit the files in the directory 'bin' in the publish folder. To reach this result just replace <DestinationRelativePath>Extra Files ... with <DestinationRelativePath>bin ...Seltzer
It should also be mentioned that if you wish to exclude folders, you must define an item named <ExcludeFromPackageFolders> in the same manner as <ExcludeFromPacakageFiles>Caines
What if you just want to add two specific files, not an entire folder?Grisgris
There is literally no documentation anywhere about this stuff. Microsoft documentation references your blogs.Concentric
@Grisgris If you just need specific files and not a folder, just change the _CustomFiles to include those specific files instead of adding recursively with ***. So something like <_CustomFiles Include="..\Dependencies\FileA.dll" /><_CustomFiles Include="C:\Someotherplace\FileB.txt" /> Something similar to that.Tarn
@SimonFrancesco I experienced this as well, and the necessary change seems to have been to extend <CopyAllFilesToSingleFolderForMsdeployDependsOn> rather than the <CopyAllFilesToSingleFolderForPackageDependsOn> as written in the above answer.Tarn
asp.net/mvc/overview/deployment/visual-studio-web-deployment/…Roxi
How would you implement this configuration in VSTS?Pr
Important to note: the "_CustomFiles Include" path is relative to the solution, not the project.Lycaonia
I had an issue where this worked when publishing to a folder, but not when publishing using web deploy. I changed CopyAllFilesToSingleFolderForPackageDependsOn to CollectFilesFromContentDependsOn and now it works.Varicotomy
For VS 2015 its in Microsoft.Web.Publishing.targets and to override its <CopyAllFilesToSingleFolderForPackageDependsOn> CustomCollectFiles; $(OnBeforeCopyAllFilesToSingleFolderForPackage); $(CopyAllFilesToSingleFolderForPackageDependsOn); </CopyAllFilesToSingleFolderForPackageDependsOn>Faubion
W
13

I found a workaround for the problem by using the ExcludeFilesFromDeployment element within the project file. I got the idea from Web Deployment: Excluding Files and Folders

So if you need to package project files as they exist in your project directory after a successful build and associated post build steps then do the following.

  1. Edit "Package/Publish Web" project settings and
    select Items to deploy to be "All files in this project folder"

  2. Unload the project

  3. Right click on the unloaded project and select to edit the project config

  4. Locate the PropertyGroup element associated to the configuration setting e.g. "Release"

  5. Within the PropertyGroup element add in the following elements and exclude files and folders you don't want in the package

    <ExcludeFilesFromDeployment>*.cs;**\.svn\**\*.*;Web.*.config;*.csproj*</ExcludeFilesFromDeployment>
    <ExcludeFoldersFromDeployment>.svn;Controllers;BootstrapperTasks;Properties</ExcludeFoldersFromDeployment>
    
  6. Save and reload your project

This solves my problem for the time being but if there is a better solution then please let me know, as this is not ideal due to the hackery involved, but then again perhaps this is an uncommon deployment scenario?

Wellmeaning answered 29/6, 2010 at 11:53 Comment(0)
W
9

Select your files or folders and Change Build action as Content from Properties Window.

Wiedmann answered 29/1, 2014 at 12:45 Comment(5)
Right, but additionaly you have to select "Copy if newer" or "Copy always", because otherwise the default action is "Do not copy", even if "Content" is selected.Barbershop
agree with matt for additional stepWiedmann
No Build action exists for folders (VS2013)Amandaamandi
copytooutputdirectory = Copy AlwaysWiedmann
Worked even without Copy Always.Karajan
H
3

I know its a old question but none of these worked for me .

In 2017 VS I just right clicked on the extra folder to be published and select publish it worked.

Example:

enter image description here

Hulk answered 22/4, 2018 at 15:37 Comment(2)
Although it is a tiny extra step it is very simple.Minnick
It's true that it's simple, but an extra step, however tiny, is still something that can be forgotten about and adds more room for error. If this is a one-off thing, this is a fine solution, but otherwise, something more automatic would be preferable.Scourge
K
0

Adding the bin folder (and it's contents) to the project caused the files to be copied to the publish output directory.

For me, my issue was that I needed to place a proprietary software license file in the bin/ folder, but did not want to copy it manually each deployment.

This was using Visual Studio 2015 Professional

Knp answered 16/3, 2017 at 22:3 Comment(0)
P
0

I know this is an old conversation but I came upon it while trying to do the same thing and I thought it would be helpful to add what I found here.

Nearly all the articles about including extra files in your publication use this method of adding the CopyAllFilesToSingleFolderForPackageDependsOn or CopyAllFilesToSingleFolderForMSDeployDependsOn items in the PropertyGroup and they all same something like "I added this to the end of the file ..."

This is what I did and spent an afternoon trying to find why nothing was happening until I realised there was already a PropertyGroup section at the top of the file. When I put my CopyAllFilesToSingleFolderForPackageDependsOn into that section it worked fine.

Hope this saves someone time some day

Punkah answered 25/9, 2018 at 8:37 Comment(0)
M
0

I had same problem. resolve was a use CopyToPublishDirectory in .csproj

 <Content Include="Data\Reports\Статистика по пользователям\lib.dll">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
          <CopyToPublishDirectory>Always</CopyToPublishDirectory>
      </Content>
Mettah answered 12/10, 2023 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.