Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
642 views
in Technique[技术] by (71.8m points)

visual studio 2010 - Why does MSBuild ignore my BeforePublish target?

I must be missing something obvious here, but I have this at the end of my ASP.NET MVC web project's .csproj file:

    [...]
    <Target Name="BeforePublish">
        <Error Condition="'foo'=='foo'" Text="test publish error" />
    </Target>
</Project>

As far as I can tell, that should always cause the publish to fail with an error. Yet, if I load the project, right-click on it, and click "Publish", the thing publishes without a hitch. What am I missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer I finally came up with which works well for Visual Studio 2010 and Visual Studio 2012; put this just before the end of your web application's .csproj file:

<Project...
    [...]
    <!-- The following makes sure we can't accidentally publish a non-Release configuration from within Visual Studio -->
    <Target Name="PreventNonReleasePublish2010" BeforeTargets="PipelinePreDeployCopyAllFilesToOneFolder" Condition="'$(BuildingInsideVisualStudio)'=='true' AND '$(VisualStudioVersion)'=='10.0'">
        <Error Condition="'$(Configuration)'!='Release'" Text="When publishing from Visual Studio 2010, you must publish the Release configuration!" />
    </Target>
    <Target Name="PreventNonReleasePublish2012" BeforeTargets="MSDeployPublish" Condition="'$(BuildingInsideVisualStudio)'=='true' AND '$(VisualStudioVersion)'=='11.0'">
        <Error Condition="'$(Configuration)'!='Release'" Text="When publishing from Visual Studio 2012, you must publish the Release configuration!" />
    </Target>
</Project>

Read on to see my thinking behind this answer, but basically it revolves around the fact that Visual Studio 2010 defines the PipelinePreDeployCopyAllFilesToOneFolder Target to hook on to, and Visual Studio 2012 defines the more "standard" MSDeployPublish Target to hook on to.

The above code only allows deploy publishing when in a Release configuration from within Visual Studio, but it could easily be modified to prevent all deploy publishing from within Visual Studio.

AFAIR, "Publish" from Visual Studio 2010 context menu invokes webdeploymsdeploy tool. I played with it a bit, but I didn't liked at all. If you still want to use this functionality and insert your target somewhere - you need to know the exact target and its dependency property.

Check c:Program Files (x86)MSBuildMicrosoftVisualStudiov10.0WebMicrosoft.Web.Publishing.targets

You will find two tasks - MSDeploy and VSMSDeploy. The latter one sounds right for me. The first one is not used in this file at all. But VSMSDeploy used in three different targets, PackageUsingManifest, TestDeployPackageToLocal and MSDeployPublish. Again the latter one sounds good ;)

<Target Name="MSDeployPublish" DependsOnTargets="$(MSDeployPublishDependsOn)">

So you just need to override one property. Put this before your target and "YourTargetName" will be called right before MSDeployPublish.

<PropertyGroup>
    <MSDeployPublishDependsOn Condition="'$(MSDeployPublishDependsOn)'!=''">
        $(MSDeployPublishDependsOn);
        YourTargetName;
    </MSDeployPublishDependsOn>
  </PropertyGroup>

If you already switched to MSBuild 4.0, there is an easier way to hook your target. You just need to specify the BeforeTarget attribute. In our case it will be like this:

  <Target Name="MyTarget" BeforeTargets="MSDeployPublish">
        <Error Condition="'foo'=='foo'" Text="test publish error" />
  </Target>

I hope this helps. Ask if you have more questions.

PS: I didn't checked all that, because I don't have any MSDeploy-ready environments ;)

NB: I remember that I was discouraged from using MSDeploy for our own products because it was pretty counter-intuitive to properly configuring it for a continuous integration (CI) system. Maybe I wasn't very good at that, and your solution will work properly. But proceed with MSDeploy carefully.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...