ChatGPT解决这个技术问题 Extra ChatGPT

如何仅为调试构建运行 Visual Studio 构建后事件

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

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


J
Jakub Konecki

构建前和构建后事件作为批处理脚本运行。您可以对 $(ConfigurationName) 执行条件语句。

例如

if $(ConfigurationName) == Debug xcopy something somewhere

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

仅供参考,您不需要使用 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" <--No space around ==
就我而言,Visual Studio 2017 $(ConfigurationName) 为空(构建后事件命令行)。 if "$(Configuration)" == "Debug" 为我工作。顺便说一句,如果您想在所有其他配置中执行某些操作,请使用 if NOT "$(Configuration)" == "Debug"
P
Peter Mortensen

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

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

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

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

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 批处理脚本中一直是完全正常的。
D
Daniel Earwicker

从 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 属性的条件。
P
Peter Mortensen

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)"
您的脚本是正确的,但我的脚本允许为不同的配置复制不同的文件。
P
Peter Mortensen

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

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

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


p
plcnut

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

  <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>

有趣的是,这不仅回答了我关于 Condition 的问题,而且也解决了我一直在寻找的问题:将 Powershell 作为 VS Build 的一部分运行。因此,我向您发送 100000000000 票,您就赢了。
P
Peter Mortensen

这适用于我在 Visual Studio 2015 中。

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

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

MySolutionFolder ....MyProject 库

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

P
Peter Mortensen

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


在 IDE 中创建时,构建事件并不特定于任何配置。
在 VS2015 中也不起作用。不可根据配置进行配置。
这仅适用于 Visual Studio 中的 C++ 项目,不适用于 C#
P
Peter Mortensen

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

if $(Configuration) == Debug xcopy

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

https://i.stack.imgur.com/CWF67.png

比较:Macros for Build Commands and Properties


您想使用 ConfigurationName。这张图片......真的很难理解所有的模糊。