在实际发布之前调用 IIS 的发布配置文件 XML 下的发布后脚本

Posted

技术标签:

【中文标题】在实际发布之前调用 IIS 的发布配置文件 XML 下的发布后脚本【英文标题】:Post-Publish Script under Publish Profile XML for IIS getting called before actual publish 【发布时间】:2020-11-12 21:22:08 【问题描述】:

我试图弄清楚Pre-PublishPost-Publish 脚本如何与MSBuild 部署一起使用IIS 来自Visual Studio 2019

下面是我的customprofile.pubxml 文件:

当我发布时,输出窗口会打印消息,但 Post-Publish 也发生在实际发布之前。

不确定这里发生了什么。

【问题讨论】:

嗨,关于这个问题的任何更新?请检查我的回答是否有帮助,并让我们知道有关它的任何反馈。我们愿意进一步帮助您:) 【参考方案1】:

其实AfterPublishBeforePublish用于ClickOnce发布(windows项目发布)而不是Asp.Net web项目发布。

您显示的内容并不能证明目标AfterPublish在构建过程下执行,而只是在构建日志中列出。

请在Tools-->Options-->Projects and Solutions下将MSBuild project build output verbosity设置为Diagnostic -->构建并运行以获取详细日志。

有a similar case about this issue。

========================================

我建议你做这个测试:

测试

我写了一个错误目标,比如:

<Target Name="BeforePublish">
    <Exec Command="123">
    </Exec>
  </Target>

如果项目在发布过程中检测到错误,则表示该项目有系统目标。

Winform 项目检测到错误,而 Web 项目没有。

其实,当你点击web项目上的Publish按钮时,它实际上会执行WebMSDeployPublish,并且由于web publish不包含AfterPublishBeforePublish 目标,您应该在它们上指定一个从属目标。

解决方案

使用这些:

<Target Name="BeforePulish" BeforeTargets="GatherAllFilesToPublish">
.....

</Target>

<Target Name="AfterPublish" AfterTargets="GatherAllFilesToPublish">

.......

</Target>

================================================

更新 1

很抱歉没有详细列出有关该问题的所有提示。

问题应该分为两种情况:

================================================

网络框架项目

对于Net Framework web 项目发布

其实Net Framework项目中,并没有明显的系统默认目标BeforePublishAfterPublishGatherAllFilesToPublish 是核心发布步骤,也是发布过程中执行的最后一个目标。

但是,net framework web publish 进程下的所有目标都在发布文件夹生成之后运行,这意味着它们都类似于 BeforePublish。

Net Framework Web Publish的特殊功能。将所有文件复制到发布文件夹是在发布过程的最后一个目标之后。因此,您不能创建依赖于最后一个默认系统目标的自定义目标。这很烦人。至少在默认情况下,您不能对 Net Framework Web Publish 案例中的发布文件进行任何自定义目标。

生成发布文件夹后可以看到没有其他系统自定义目标运行。

但是,我为您提供了一个解决方案,它可能有点复杂。并且可以在发布文件夹生成后完成工作。

解决方案

1) 首先,您应该安装一个名为 MSBuild.Extension.Pack 的 nuget 包,它是 msbuild 任务的额外扩展。

它有一个名为AsyncExec 的任务,它可以与以下目标一起执行。在运行时,它将继续执行发布的后续步骤。只需让命令休眠一段时间,等待发布文件夹生成,即可修改发布文件夹。

2) 写在xxx.pubxml 文件下:

<Target Name="custom step" AfterTargets="GatherAllFilesToPublish">

    <AsyncExec Command="powershell.exe sleep 2;powershell.exe -file xxxxx"></AsyncExec>
          
</Target>

睡眠时间取决于项目的大小以及发布文件夹所需的时间。

而且这个功能在我这边效果很好。

================================================ ===

Asp Net Core 项目发布

对于 Asp Net Core Web 项目发布,

它有AfterPublishBeforePublish 系统默认目标。 AfterPublish 目标是在将所有文件复制到发布文件夹之后,以便您也可以直接使用该系统目标。并且它也是net core web 发布过程的最后一个目标。这相当于框架发布过程的_TransformWebConfigForAzureAuthentication

截图的第一行和前面的内容是生成publish文件夹的过程。您可以检查将所有文件复制到发布文件夹中是否在 AfterPublish 目标之前。

并且您可以发现对于dotnet publish,有一个名为AfterPublish 的真实目标,它在publish 文件夹生成之后运行。

但是,只是这个系统的默认目标不能被覆盖,只能依赖。

所以你应该这样使用:

<Target Name="custom step1" BeforeTargets="BeforePublish">

<Exec Command=""/>

</Target>

<Target Name="custom step2" AfterTargets="AfterPublish">
 
<Exec Command=""/>

</Target>

说实话dotnet web publishframework web publish做了更大的优化,确实解决了这个问题,对老的framework web publish没有任何改进,所以我们必须寻求其他解决方法。

结论

Winform 项目发布,它有AfterPublishBeforePublish 目标,你可以直接覆盖它们。

Net Framework web 发布,它没有AfterPublishBeforePublish 目标,你应该使用其他方式。

Asp Net Core 网络发布,它有 AfterPublishBeforePublish 目标,它们不能被覆盖,您应该使用依赖于它们的自定义目标。

【讨论】:

谢谢。它适用于BeforePublish 事件。但是发布完成后执行的目标名称是什么? 首先,我很好奇你的项目类型是什么,是asp net core项目还是asp net framework项目? 其实在net framwork项目中,并没有明显的系统默认目标BeforePublishAfterPublishGatherAllFilesToPublish 是核心发布步骤,也是发布流程下执行的最后一个目标。不过需要注意的是,如果你想修改那个目标发布下的这些文件,恐怕不能这样。但是,net framework web publish 进程下的所有目标都在发布文件夹生成之后运行,这意味着它们都类似于 BeforePublish。 所以似乎不可能在框架网络发布下做AfterPublish这样的工作。它是网络框架网络发布的特殊功能。将所有文件复制到发布文件夹是在发布过程的最后一个目标之后。因此,您不能创建依赖于最后一个默认系统目标的自定义目标。这很烦人。至少在默认情况下,您不能通过任何自定义目标对框架 Web 发布案例中的发布文件进行任何更改。 但是对于asp net web project publish,很抱歉一开始没有列出这个技巧,它有AfterPublishBeforePublish系统目标。 afterpublish 目标是在将所有文件复制到发布文件夹之后,以便您也可以使用该系统目标。并且它也是net core web 发布过程的最后一个目标。所以它完全符合我们的要求。

以上是关于在实际发布之前调用 IIS 的发布配置文件 XML 下的发布后脚本的主要内容,如果未能解决你的问题,请参考以下文章

IIS7 设置文件位置

配置文件不是格式良好的 XML #2

IIS无法启动报错配置文件的XML格式不正确如何处理

从数据库中导出 XML 文件并在实际列之前获得没有任何属性的干净格式

在发送请求之前/不发送请求之前检查由 PHP SoapClient 调用创建的 XML

是否可以编写 .XML 文件的脚本