Search code examples
visual-studioiismsbuildpublish

Post-Publish Script under Publish Profile XML for IIS getting called before actual publish


I am trying to figure out how Pre-Publish and Post-Publish scripts work with MSBuild deployment for IIS from Visual Studio 2019.

Below is my customprofile.pubxml file:

enter image description here When I publish the output windows prints messages but Post-Publish also happened before actual publish.

enter image description here

Not sure what's happening here.


Solution

  • Actually, AfterPublish and BeforePublish are used for ClickOnce publish(windows project publish) rather than Asp.Net web project publish.

    What you shows does not prove the target AfterPublish execute under the build process but only list in the build log.

    Please set MSBuild project build output verbosity to Diagnostic under Tools-->Options-->Projects and Solutions-->Build and Run to get the detailed log.

    There is a similar case about this issue.

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

    I suggest you do this test:

    Test

    I write an error target like:

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

    If the project detects the error during publish, it means the project has the system targets.

    The Winform project detects the error while the web project does not.

    In fact, when you click Publish button on web project, it actually executes WebMSDeployPublish and since web publish does not contains AfterPublish and BeforePublish targets, you should specify a dependenttarget on them.

    Solution

    Use these:

    <Target Name="BeforePulish" BeforeTargets="GatherAllFilesToPublish">
    .....
    
    </Target>
    
    <Target Name="AfterPublish" AfterTargets="GatherAllFilesToPublish">
    
    .......
    
    </Target>
    

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

    Update 1

    Sorry for not listing all the tips about the issue in detailed.

    The problem should be divided into two cases:

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

    Net Framework project

    For Net Framework web project publish,

    Actually in Net Framework project, there is no obvious system default targets called BeforePublish and AfterPublish. The GatherAllFilesToPublish is the core publish step and also the last target that executes under the publish process.

    enter image description here

    However, all targets under the net framework web publish process run after the generation of the publish folder which means that they are all like BeforePublish.

    It is the special feature of Net Framework Web Publish. Coping all files into publish folder is after the last target of the publish process. So you cannot make a custom target that depends on the last default system target. It is quite annoying. At least by default, you can't make any custom targets to make any changes to publish files in the Net Framework Web Publish case.

    You can see that there is no other system custom target runs after generating the publish folder.

    enter image description here

    However, I have one solution for you and it might be a bit complex. And it can do a job after the generation of the publish folder.

    Solution

    1) First, you should install a nuget package called MSBuild.Extension.Pack which is an extra extension for msbuild tasks.

    It has a task called AsyncExec which can executes with the following targets. While it is running, it will continue to execute the next steps of publish. You only need to make the command sleep for a while and wait the publish folder to be generated so that you can modify that publish folder.

    2) write this under xxx.pubxml file:

    <Target Name="custom step" AfterTargets="GatherAllFilesToPublish">
    
        <AsyncExec Command="powershell.exe sleep 2;powershell.exe -file xxxxx"></AsyncExec>
              
    </Target>
    

    The sleep time is up to the the size of your project and how long it takes to publish the folder.

    And this function works well in my side.

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

    Asp Net Core project publish

    For Asp Net Core web project publish,

    It has AfterPublish and BeforePublish system default target. And AfterPublish target is after copying all files into the publish folder so that you can use that system target directly as well. And it is also the last target of the net core web publish process. And this is equivalent to _TransformWebConfigForAzureAuthentication of Framework Publish process.

    enter image description here

    The first line of the screenshot and the previous content is the process of generating the publish folder. You can check that the copying all files into publish folder is before the AfterPublish target.

    And you can find that for dotnet publish, there is a real target called AfterPublish and it runs after the generation of the publish folder.

    However, It is just that the default target of this system cannot be overwritten, it can only be depended on.

    So you should use like this:

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

    To be honest, dotnet web publish has made greater optimizations compared to framework web publish, and it does solve this problem, and it does not make any improvements to the old framework web publish, so we have to seek other workarounds.

    Conclusion

    Winform project publish, it has AfterPublish and BeforePublish targets and you can overwrite them directly.

    Net Framework web publish, it does not have AfterPublish and BeforePublish targets and you should use other ways.

    Asp Net Core web publish, it has AfterPublish and BeforePublish targets and they cannot be overwritten and you should use custom targets that depends on them.