【问题标题】:How to get Visual Studio 'Publish' functionality to include files from post build event?如何获得 Visual Studio 的“发布”功能以包含来自构建后事件的文件?
【发布时间】:2011-03-09 10:46:36
【问题描述】:

我目前正在尝试使用 Visual Studio 2010 的“发布”和 MSDeploy 功能来处理我的 Web 部署需求,但在根据我的构建配置自定义包方面遇到了障碍。

我在 32 位环境中开发,但需要为 64 位环境创建发布包,因此在“发布”配置中,我有一个构建后事件,将第三方 dll 的 64 位版本复制到 bin 目录覆盖32位版本。当我使用“发布”功能时,即使将正确的 64 位 dll 复制到 bin 目录,它也不会包含在包中。

有没有办法让“发布”包含在构建后事件期间复制到 bin 目录中的文件?

【问题讨论】:

  • 如果您改用 pre-build 事件,这似乎已经按照您的意愿工作了(Visual Studio 2013,ASP.NET 项目模板)。
  • 他们似乎已在 Visual Studio 2015 及更高版本中删除了上述评论中提到的预构建行为。

标签: asp.net visual-studio-2010 build-process publishing msdeploy


【解决方案1】:

我在How do you include additional files using VS2010 web deployment packages? 回答了一个类似但不同的问题。

在您使用构建后事件的场景中,我建议您删除构建后事件并使用您自己的 MSBuild 目标而不是构建后事件来实施您的操作。您将在下面找到另一个答案的文本。


发件人:How do you include additional files using VS2010 web deployment packages?


很好的问题。我刚刚在Web Deployment Tool (MSDeploy) : Build Package including extra files or excluding specific files 上发布了一篇非常详细的博客文章。

这里是概要。包含文件后,我还将展示如何排除文件。

包括额外文件

在包中包含额外的文件有点困难,但如果您对 MSBuild 感到满意,但仍然没有什么大不了的,如果您不熟悉,请阅读本文。为了做到这一点,我们需要挂钩收集用于打包的文件的过程部分。我们需要扩展的目标称为CopyAllFilesToSingleFolder。这个目标有一个依赖属性PipelinePreDeployCopyAllFilesToOneFolderDependsOn,我们可以利用它并注入我们自己的目标。因此,我们将创建一个名为 CustomCollectFiles 的目标并将其注入到进程中。我们通过以下方式实现这一点(请记住在 import 语句之后)。

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

这会将我们的目标添加到流程中,现在我们需要定义目标本身。假设您有一个名为 Extra Files 的文件夹,它位于您的 Web 项目上方 1 级。您想要包含所有这些文件。这里是CustomCollectFiles 目标,我们之后再讨论。

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

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

我在这里所做的是创建项目 _CustomFiles 并在 Include 属性中告诉它拾取该文件夹中的所有文件以及它下面的任何文件夹。然后我使用这个项目来填充FilesForPackagingFromProject 项目。这是 MSDeploy 实际用于添加额外文件的项目。另请注意,我声明了元数据 DestinationRelativePath 值。这将确定它将被放置在包中的相对路径。我在这里使用了 Extra Files%(RecursiveDir)%(Filename)%(Extension) 声明。这就是说将它放在包中与 Extra Files 文件夹下相同的相对位置。

排除文件

如果您打开使用 VS 2010 创建的 Web 应用程序的项目文件,您会在其底部找到一行。

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

顺便说一句,您可以在 VS 中打开项目文件。右键单击项目选择卸载项目。然后右键单击卸载的项目并选择编辑项目。

此声明将包括我们需要的所有目标和任务。如果您不确定是否在之后进行,我们的大多数定制都应该在该导入之后!因此,如果您有要排除的文件,则可以使用项目名称ExcludeFromPackageFiles 来执行此操作。例如,假设您有一个名为 Sample.Debug.js 的文件,该文件包含在您的 Web 应用程序中,但您希望将该文件从创建的包中排除。您可以将 sn-p 放在该 import 语句之后。

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

通过声明填充此项,文件将被自动排除。请注意此处FromTarget 元数据的使用。我不会在这里讨论,但你应该知道总是指定。

【讨论】:

  • @Sayed,这似乎不适用于 VS2012,您知道如何针对这种情况进行更新。更改为 v11.0 不起作用。 TIA。
  • 实际上没有关于这些东西的任何文档。 Microsoft 文档引用了您的博客。
  • @Daniel 如果您只需要特定文件而不是文件夹,只需更改 _CustomFiles 以包含这些特定文件,而不是使用 *** 递归添加。所以像 <_customfiles include="..\Dependencies\FileA.dll"><_customfiles include="C:\Someotherplace\FileB.txt"> 类似的东西。
  • @SimonFrancesco 我也遇到过这种情况,必要的改变似乎是扩展 而不是 上面的答案。
【解决方案2】:

我通过在项目文件中使用ExcludeFilesFromDeployment 元素找到了解决该问题的方法。我的想法来自Web Deployment: Excluding Files and Folders

因此,如果您需要在成功构建和相关的构建后步骤后打包项目目录中存在的项目文件,请执行以下操作。

  1. 编辑“打包/发布 Web”项目设置和
    选择要部署的项目为“此项目文件夹中的所有文件”
  2. 卸载项目
  3. 在卸载的项目上右键选择编辑项目配置
  4. 找到与配置设置关联的PropertyGroup 元素,例如“释放”
  5. PropertyGroup 元素中添加以下元素并排除包中不需要的文件和文件夹

    <ExcludeFilesFromDeployment>*.cs;**\.svn\**\*.*;Web.*.config;*.csproj*</ExcludeFilesFromDeployment>
    <ExcludeFoldersFromDeployment>.svn;Controllers;BootstrapperTasks;Properties</ExcludeFoldersFromDeployment>
    
  6. 保存并重新加载您的项目

这暂时解决了我的问题,但如果有更好的解决方案,请告诉我,因为这并不理想,因为涉及黑客,但也许这是一个不常见的部署场景?

【讨论】:

    【解决方案3】:

    从属性窗口中选择您的文件或文件夹并将生成操作更改为内容。

    【讨论】:

    • 对,但是另外你必须选择“如果更新就复制”或“始终复制”,否则默认操作是“不复制”,即使选择了“内容”。
    • 同意 matt 的额外步骤
    • 文件夹不存在构建操作 (VS2013)
    • copytooutputdirectory = 始终复制
    • 即使没有 Copy Always 也能正常工作。
    【解决方案4】:

    我知道这是一个老问题,但这些都不适合我。

    在 2017 VS 中,我只是右键单击要发布的额外文件夹并选择发布它工作。

    示例:

    【讨论】:

    • 虽然是一个小小的额外步骤,但非常简单。
    • 确实很简单,但是额外的步骤,无论多么微小,仍然是可以忘记的,并且增加了更多的错误空间。如果这是一次性的,这是一个很好的解决方案,但否则,更自动的东西会更好。
    【解决方案5】:

    将 bin 文件夹(及其内容)添加到项目导致文件被复制到发布输出目录。

    对我来说,我的问题是我需要将专有软件许可证文件放在 bin/ 文件夹中,但不想在每次部署时手动复制它。

    这是使用 Visual Studio 2015 Professional

    【讨论】:

      【解决方案6】:

      我知道这是一个古老的对话,但我在尝试做同样的事情时遇到了它,我认为添加我在这里找到的内容会有所帮助。

      几乎所有关于在您的出版物中包含额外文件的文章都使用这种在PropertyGroup 中添加CopyAllFilesToSingleFolderForPackageDependsOnCopyAllFilesToSingleFolderForMSDeployDependsOn 项目的方法,它们都类似“我在文件末尾添加了这个。 ..”

      这就是我所做的,花了一个下午试图找出为什么什么都没有发生,直到我意识到文件顶部已经有一个 PropertyGroup 部分。当我将CopyAllFilesToSingleFolderForPackageDependsOn 放入该部分时,它运行良好。

      希望这能节省一些人的时间

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-02
        • 2013-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多