为什么MSBuild会忽略我的BeforePublish目标?

Jez*_*Jez 10 msbuild visual-studio-2010

我必须在这里遗漏一些明显的东西,但我在ASP.NET MVC Web项目.csproj文件的末尾有这个:

    [...]
    <Target Name="BeforePublish">
        <Error Condition="'foo'=='foo'" Text="test publish error" />
    </Target>
</Project>
Run Code Online (Sandbox Code Playgroud)

据我所知,这应该总是导致发布失败并出现错误.然而,如果我加载项目,右键单击它,然后单击"发布",这个东西会毫不费力地发布.我错过了什么?

Ale*_*bak 15

我最终提出的答案适用于Visual Studio 2010和Visual Studio 2012; 把它放在Web应用程序.csproj文件结束之前:

<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>
Run Code Online (Sandbox Code Playgroud)

继续阅读以了解我对这个答案背后的想法,但基本上它围绕着Visual Studio 2010定义PipelinePreDeployCopyAllFilesToOneFolder要挂钩的目标的事实,并且Visual Studio 2012定义了更多"标准" MSDeployPublish目标要挂钩.

上述代码仅允许Release在Visual Studio 中的配置中进行部署发布,但可以轻松修改它以防止在Visual Studio中进行所有部署发布.

AFAIR,Visual Studio 2010上下文菜单中的"发布"调用webdeploy\msdeploy工具.我玩了一下,但我根本不喜欢.如果您仍想使用此功能并在某处插入目标 - 您需要知道确切的目标及其依赖属性.

校验 c:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets

您将找到两个任务 - MSDeploy和VSMSDeploy.后者听起来对我来说很合适.第一个根本没用在这个文件中.但VSMSDeploy用于三个不同的目标,PackageUsingManifest,TestDeployPackageToLocal和MSDeployPublish.后者再次听起来不错;)

<Target Name="MSDeployPublish" DependsOnTargets="$(MSDeployPublishDependsOn)">
Run Code Online (Sandbox Code Playgroud)

所以你只需要覆盖一个属性.将它放在目标之前,将在MSDeployPublish之前调用"YourTargetName".

<PropertyGroup>
    <MSDeployPublishDependsOn Condition="'$(MSDeployPublishDependsOn)'!=''">
        $(MSDeployPublishDependsOn);
        YourTargetName;
    </MSDeployPublishDependsOn>
  </PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

如果您已经切换到MSBuild 4.0,则可以更轻松地挂钩目标.您只需指定BeforeTarget属性即可.在我们的例子中它将是这样的:

  <Target Name="MyTarget" BeforeTargets="MSDeployPublish">
        <Error Condition="'foo'=='foo'" Text="test publish error" />
  </Target>
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助.询问您是否有更多问题.

PS:我没有检查所有这些,因为我没有任何MSDeploy就绪环境;)

注意:我记得我不鼓励将MSDeploy用于我们自己的产品,因为为连续集成(CI)系统正确配置MSDeploy非常违反直觉.也许我不是很擅长,你的解决方案也能正常运作.但请小心使用MSDeploy.


小智 5

不确定它是否可以在 VS 2010 中工作,因为我只在 VS 2012 中测试过,但我发现将目标放在 (ProjectDir)/Properties/PublishProfiles/(ProfileName).pubxml 文件中作为“AfterBuild”目标作品。如在,它不会在您构建项目时触发,但会在您发布项目时触发。

所以而不是把

<Target Name="BeforePublish">
    <Error Condition="'foo'=='foo'" Text="test publish error" />
</Target>
Run Code Online (Sandbox Code Playgroud)

在您的 .csproj 文件中,尝试放置

<Target Name="AfterBuild">
    <Error Condition="'foo'=='foo'" Text="test publish error" />
</Target>
Run Code Online (Sandbox Code Playgroud)

在您的 .pubxml 文件中,它应该在发布之前触发。