在 Visual Studio 中发布事件之后

Posted

技术标签:

【中文标题】在 Visual Studio 中发布事件之后【英文标题】:After Publish event in Visual Studio 【发布时间】:2012-12-08 20:48:02 【问题描述】:

我试图在发布事件后调用简单任务。当我说“发布”时,我的意思是在 Visual Studio 中发布,右键单击项目并按“发布...”。我已经在项目文件中包含(导入的)目标文件,它工作正常,因为我已经在 Build 事件中对其进行了测试。 我在http://msdn.microsoft.com/en-us/library/ms366724.aspx 发现有 AfterPublish 事件应该可以满足我的需要,但它没有。 我不确定这是否是应该在 Visual Studio 中发布时触发的同一事件,请有人澄清这一点。 我的问题是如何在 Visual Studio 中发布目标文件中触发任何类型的任务?

我已经在目标文件中尝试过这个:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="AfterPublish">
        <Message Label="Test"></Message>        
        <Warning Label="Test"></Warning>
    </Target>   
</Project>

我正在使用 Visual Studio 2010。

编辑:

我实际上正在寻找在 Visual Studio 中对 Publish 执行某些操作的任何方法。我也在考虑添加构建事件,但我不知道如何确定它是否正在进行发布。

编辑: @Alexey Shcherbak 感谢您的快速回复。 我在我的 MSBuild 输出中得到了这个:

12/10/2012 12:29:40 AM:        Done executing task "CallTarget".
12/10/2012 12:29:40 AM:        Done building target "PipelinePreDeployCopyAllFilesToOneFolder" in project "PublishTestApp.csproj".
12/10/2012 12:29:40 AM:Done building project "PublishTestApp.csproj".
Deleting existing files...
Publishing folder /...
Publishing folder Account...
Publishing folder bin...
Publishing folder Scripts...
Publishing folder Styles...
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========

所以我的任务将在 PipelinePreDeployCopyAllFilesToOneFolder 之后但在文件实际处理之前执行,我不认为此时发布已经完成。 当然,我确实对此进行了实际测试,因此在 MSBuild 任务中,我正在执行从假定复制到 Publish 文件夹中的文本文件的简单读取,但它失败了。

【问题讨论】:

添加了另一部分以回复您的编辑 【参考方案1】:

发布上下文菜单未运行“发布”目标(如果我们谈论的是发布网站,而不是发布 ClickOnce 包)。

如果您使用的是 VS2010 - 上下文菜单将运行“PipelinePreDeployCopyAllFilesToOneFolder”目标,而在 VS2012 中(如果要切换,请记住这一点)它将运行“MSDeployPublish”目标。

我想你应该阅读this question and answer。 Jez 和我就如何挂钩到 Before\After 发布目标提供了相当全面的答案。

简而言之 - 对于 MSBuild 版本>=4.0,您可以使用这种方法

<Target Name="Mytarget" AfterTargets="PipelinePreDeployCopyAllFilesToOneFolder" >
    <Message Label="Test"></Message>        
    <Warning Label="Test"></Warning>
</Target>

@Edit1:使用 CopyAllFilesToSingleFolderForPackage 而不是 PipelinePreDeployCopyAllFilesToOneFolder - 应在此目标之后复制文件。 如果您仅在目标在 VS 上下文中启动时才需要触发目标 - 检查我发布的链接并添加更多条件 - 检查 Visual Studio 的启动,如 Condition="'$(BuildingInsideVisualStudio)'=='true' AND '$(VisualStudioVersion)'=='10.0'" 如果您添加更多上下文,例如您想在发布后启动什么样的目标等 - 它可以添加更多上下文并帮助其他人理解问题

【讨论】:

这是我正在寻找的Target(如果那里有描述所有 MSBuild 目标的博客文章,我会很感激有人分享它)。我的问题是我希望转换文件只打开发布,而不是构建。 @RobScott AFAIK 没有这样的事情 - MSBuild 的设计方式意味着您的目标集及其版本(和覆盖)对于您的机器来说是非常独特的,并且取决于什么 SDKs \ 项目类型 \您已安装的 msbuild 和 VS 版本。它会根据您的环境动态地编写构建脚本。这非常强大,但同时也非常脆弱。所以它不可能有任何全面的目标清单。你可以学习如何阅读它的详细日志以及如何阅读 .targets 文件本身,这样你就可以找到你需要的东西,但是没有备忘单 =( @AlexeyShcherbak 我的意思是PipelinePreDeployCopyAllFilesToOneFolder 目标任务。但是,我不得不将我的更改为CopyAllFilesToSingleFolderForPackage。你可以在这里阅读我的问题——***.com/questions/42284979/…【参考方案2】:

更新:似乎在 VS 2019 和 .NET 5 中您现在可以使用 Publish 目标。

<Target Name="Test" AfterTargets="Publish">
    <Exec Command="blablabla" />
</Target>

这也是我的旧答案:


MS 已确认,在发布到文件系统时他们没有任何目标可在此之后启动。

"我们目前不支持在发布后执行自定义目标 来自 VS 的文件系统协议。”

引自this SO question

所以我们最终做的是:

    使用AfterTargets="CopyAllFilesToSingleFolderForPackage"(在文件复制到发布位置之前运行) 执行一个 bat 文件 bat 文件以 timeout 10 命令开头(等待 10 秒) - 因为没有更好的方法。

重要提示:此 bat 文件必须异步执行,以便在启动后继续发布过程,请参阅this SO answer 了解如何执行此操作。

【讨论】:

赞成,但没有吸引力,这是真正适用于发布到文件系统的唯一方法。也就是说,AfterTargets="PublishOnly" 实际上(并且错误地)在过程中运行得比“CopyAllFilesToSingleFolderForPackage”晚一些。 这就是我在 Visual Studio 2017 上发布到文件系统时的全部功能。 您可以查看使用this answer 中描述的方法构建或发布时执行的每个任务。这就是我找到PublishOnly 的方式,这是执行的最后一个任务,或者至少在我的情况下是这样。 @Chris 很有趣!你是说AfterTargets="PublishOnly"是在复制完所有文件后执行的? @AlexfromJitbit 是的,一定是这样。【参考方案3】:

我尝试了所有其他答案,但它们都不起作用。就我而言,我正在使用 VS2015 发布 VSTO 加载项,所以可能会发生一些不同的事情,但这里有两个可行的选项:

<Target Name="AfterPublish">
  <Warning Text="publish warning 1" />
</Target>
<Target Name="CustomTarget" AfterTargets="AfterPublish">
  <Warning Text="publish warning 2" />
</Target>

我(以及其他人)对此感到困难的部分原因是Message 任务似乎没有做任何事情。我期待 Output 视图中的文本,但没有显示任何内容。在Error List 中也没有Message 项目,但是通过使用Warning,它们确实出现在Error List 中。不幸的是,我对 MSBuild 的了解不够,无法说明为什么 Message 的行为不符合预期。

编辑:请参阅this excellent answer,了解如何准确查看正在执行的目标。

【讨论】:

我在 VS.NET 2017 RC4 中尝试了这些,并且 AfterTargets="AfterPublish" 一个有效。谢谢。【参考方案4】:

我刚刚写了一篇关于我如何在 Visual Studio 2013 中实现这一点的帖子:http://www.alexdresko.com/2015/02/28/taking-visual-studio-build-and-publish-events-to-the-next-level/

本质上,这就是魔法:

<Target Name="Mytarget" AfterTargets="MSDeployPublish" >
    <Message Text="The name of the publish profile is $(DestinationAppRoot)"/>   
    .... Here's where you do something awesome... 
</Target>

我鼓励您阅读整篇文章以获取更多信息。

【讨论】:

是否还有诸如 $(DestinationAppRoot) 之类的变量可以访问目标 URL? 老实说,我不知道。尝试在整个硬盘驱动器中搜索“DestinationAppRoot”,您可能会偶然发现一些有用的东西。我真的不记得我是如何想出这里发布的解决方案的。 :) 这对我不起作用。仅供参考:我正在发布到文件系统。视觉工作室 2017。 使用文件系统发布时使用:AfterTargets="WebFileSystemPublish"【参考方案5】:

我对另一个问题的回答可能会有用。

AfterPublish script doesn't run when I publish a web app

特别是,使用“已发布文件”的路径,您可以通过$(WebProjectOutputDir)\$(WPPAllFilesInSingleFolder) 传入参数。这类似于c:\path to *.csproj\obj\build configuration\Package\PackageTmp

【讨论】:

那么也许这应该被投票为重复呢? 我不知道它是否“完全重复”......只是认为我在另一个答案上的信息可能有助于让他到达某个地方。如果您认为需要,将让您标记。谢谢。 我不是这里的学科专家。如果帖子不是重复的,请调整您对问题的回答,即使是内部链接也可能会消失,然后未来的访问者会被“请参阅此处”链接所困。

以上是关于在 Visual Studio 中发布事件之后的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 在 python 中显示错误“无法访问”

visual studio 2012如何调试和运行程序?

在 Visual Studio 中计时事件的最佳方式是啥? [关闭]

visual studio C/C++ 编程学习 visual studio 中的生成事件

Visual Studio:无法解析事件/自定义事件工具提示

是否可以在 Visual Studio Code 扩展中访问鼠标事件