【问题标题】:How to run Visual Studio post-build events for debug build only如何仅为调试构建运行 Visual Studio 构建后事件
【发布时间】:2010-09-14 02:01:18
【问题描述】:

如何将我的构建后事件限制为仅针对一种构建类型运行?

我正在使用事件将 DLL 文件复制到本地 IIS 虚拟目录,但我不希望在发布模式的构建服务器上发生这种情况。

【问题讨论】:

    标签: visual-studio build-process


    【解决方案1】:

    构建前和构建后事件作为批处理脚本运行。你可以在$(ConfigurationName)上做一个条件语句。

    例如

    if $(ConfigurationName) == Debug xcopy something somewhere
    

    【讨论】:

    • 奇怪,也许只是我,但我尝试添加 if 条件,现在我收到此错误 - 错误退出代码 255
    • 我发现整个命令需要在一行中,否则你会得到“exited with code 255”
    • 您还可以使用 gotos / labels 获得更全面的解决方案(请参阅我的 7 月 24 日的回答)
    • 并且您可以在 if 命令中使用括号(例如,请参阅我的答案)
    • 你应该使用“xcopy /Y”,这样目标目录中的文件就会被覆盖。
    【解决方案2】:

    仅供参考,您不需要使用 goto。 shell IF 命令可以使用圆括号:

    if $(ConfigurationName) == Debug (
      copy "$(TargetDir)myapp.dll" "c:\delivery\bin" /y
      copy "$(TargetDir)myapp.dll.config" "c:\delivery\bin" /y
    ) ELSE (
      echo "why, Microsoft, why".
    )
    

    【讨论】:

    • 我还要补充一点,要注意需要紧跟 if 语句的左括号,好像它在下一行会产生错误代码
    • 如果您收到错误代码 255,请使用 "$(ConfigurationName)"(注意引号)
    • 注意,如果您在 $(ConfigurationName) 周围使用“”,则还需要在 Debug 一词周围加上引号 - shell 命令 IF 语句非常......当涉及到字符串比较时。
    • 注意,为了摆脱 255,我必须在 $(ConfigurationName) 周围使用 "" 并删除条件周围的空格,例如 if "$(ConfigurationName)"=="Release"
    • 在我使用 Visual Studio 2017 的情况下,$(ConfigurationName) 为空(构建后事件命令行)。 if "$(Configuration)" == "Debug" 为我工作。顺便说一句,如果您想在所有其他配置中执行某些操作,请使用 if NOT "$(Configuration)" == "Debug"
    【解决方案3】:

    像往常一样添加您的后期构建事件。然后保存您的项目,在Notepad(或您喜欢的编辑器)中打开它,并将条件添加到 PostBuildEvent 属性组。这是一个例子:

    <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
        <PostBuildEvent>start gpedit</PostBuildEvent>
    </PropertyGroup>
    

    【讨论】:

    • 这行得通,但它会迫使您对项目文件源中的事件进行所有设计工作。 IDE 中也隐藏了其他条件构建事件声明。
    • 我不得不说这对我来说是更好的答案,但首选方法不起作用。
    • 你不需要在记事本中打开它,你可以留在Visual Studio中。您可以右键单击项目文件,单击“卸载项目”,然后再次右键单击并单击“编辑”。您现在可以使用语法着色编辑 {{csproj}} 文件。再次右键单击,但现在单击“重新加载项目”以重新加载。
    • 这种方法在我尝试的时候并没有在 PostBuildEvent 命令本身中展开宏。 cd "$(ProjectDir)" 扩展为 cd ""
    • 在 VS 2017 中,您也可以使用 &lt;Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Debug"&gt; &lt;Exec Command="your command"/&gt;&lt;/Target&gt; 执行此操作。宏变量和一切正常工作。
    【解决方案4】:

    或者(因为将事件放入批处理文件然后调用),使用以下内容(在构建事件框中,而不是在批处理文件中):

    if $(ConfigurationName) == Debug goto :debug
    
    :release
    signtool.exe ....
    xcopy ...
    
    goto :exit
    
    :debug
    ' Debug items in here
    
    :exit
    

    通过这种方式,您可以为任何配置设置事件,并且仍然使用宏对其进行管理,而不必将它们传递到批处理文件中,请记住 %1$(OutputPath) 等。

    【讨论】:

    • 如果您有机会查看反射器中的一些代码,编译器会将许多 switch/case 语句转换为 goto。
    • 大多数编译器都会将代码翻译成更简单的指令,例如 goto。逆向工程无法将更简单的指令组合成您希望看到的“好”更复杂的指令。我看不出微软是如何强制我们使用 goto 的,或者这与这篇文章有什么关系。
    • @StingyJack:如果你看一下编译后的代码,你会发现它全部都变成了 JMP 指令 :) 我不在乎编译器在幕后做了什么,只要我开始编写可读性好的代码。 (并不是说使用 goto 有时不太容易阅读)
    • 如果需要,您可以删除if 并使用goto :$(ConfigurationName)
    • @gbjbaanb 不过这不是 C#。这是 DOS 批处理脚本。而goto 在 DOS 批处理脚本中一直是完全正常的。
    【解决方案5】:

    从 Visual Studio 2019 开始,现代 .csproj 格式支持直接在 Target 元素上添加条件:

    <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Debug'">
        <Exec Command="nswag run nswag.json" />
    </Target>
    

    UI 没有提供设置方法,但如果您通过 UI 进行更改,它似乎可以安全地保留 Configuration 属性。

    【讨论】:

    • 这确实值得更高,而且他们确实应该更新 UI 以允许您标记构建配置或至少从 csproj 属性中添加条件。
    【解决方案6】:

    Visual Studio 2015:正确的语法是(保持一行):

    if "$(ConfigurationName)"=="My Debug CFG" ( xcopy "$(TargetDir)test1.tmp" "$(TargetDir)test.xml" /y) else ( xcopy "$(TargetDir)test2.tmp" "$(TargetDir)test.xml" /y)
    

    这里没有错误 255。

    【讨论】:

    • 保持一行
    • 工作得很好。 Tks
    • 你的条件技巧对我来说效果最好。然而,这在没有条件的情况下效果更好,而且更加简洁。复制 "$(ProjectDir)\..\$(ConfigurationName)\MyFileName" "$(TargetDir)"
    • 您的脚本是正确的,但我的脚本允许为不同的配置复制不同的文件。
    【解决方案7】:

    您可以将配置名称传递给构建后脚本并在其中检查它是否应该运行。

    使用$(ConfigurationName) 传递配置名称。

    检查它取决于您如何实施构建后步骤——它将是一个命令行参数。

    【讨论】:

      【解决方案8】:

      我发现我可以像这样在项目文件中放置多个条件:

        <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition=" '$(Configuration)' != 'Debug' AND '$(Configuration)' != 'Release' ">
            <Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)postBuild.ps1 -ProjectPath $(ProjectPath) -Build $(Configuration)" />
        </Target>
      

      【讨论】:

        【解决方案9】:

        这适用于我在 Visual Studio 2015 中。

        我将所有 DLL 文件从位于与我的解决方案文件夹相同级别的库文件夹中的文件夹中复制到正在构建的项目的目标目录中。

        使用我的项目目录中的相对路径,并使用..\..\lib 将文件夹结构向上两步

        我的解决方案文件夹
        ....我的项目

        if $(ConfigurationName) == Debug (
        xcopy /Y "$(ProjectDir)..\..\lib\*.dll" "$(TargetDir)"
        ) ELSE (echo "Not Debug mode, no file copy from lib")
        

        【讨论】:

          【解决方案10】:

          与任何项目设置一样,构建事件可以按配置进行配置。只需在“属性页”对话框的下拉菜单中选择要更改的配置,然后编辑构建后步骤。

          【讨论】:

          • 构建事件在 IDE 中创建时并不特定于任何配置。
          • 在 VS2015 中也不起作用。无法根据配置进行配置。
          • 这仅适用于 Visual Studio 中的 C++ 项目,不适用于 C#
          【解决方案11】:

          在 Visual Studio 2012 中您必须使用(我认为在 Visual Studio 2010 中也是如此)

          if $(Configuration) == Debug xcopy
          

          $(ConfigurationName) 被列为宏,但未分配。

          比较:Macros for Build Commands and Properties

          【讨论】:

          • 您想使用 ConfigurationName。这张图片......真的很难理解所有的模糊。
          猜你喜欢
          • 2020-08-17
          • 1970-01-01
          • 2016-08-11
          • 2016-05-21
          • 1970-01-01
          • 2015-05-06
          • 2012-10-31
          • 2011-08-18
          相关资源
          最近更新 更多