【问题标题】:Why do all Pre-build or Post-build events in Visual Studio fail with exit code 1?为什么 Visual Studio 中的所有 Pre-build 或 Post-build 事件都失败并出现退出代码 1?
【发布时间】:2026-01-15 23:00:01
【问题描述】:

我的目标是在解决方案 A 的构建后事件中将 .exe 文件从解决方案 A 的 bin 文件夹复制到另一个解决方案 B 资源文件夹。
我创建了必要的 xcopy 命令并在 powershell 中进行了试用:效果很好。
每当我向 VS 构建中的操作添加任何命令时,都会失败:“#command# exited with code 1”,其中 #command# 是例如 xcopy 命令。
我尝试以管理员身份运行 VS,目前我尝试只运行一个包含“@echo off @exit 0”的 .bat 文件。这也会导致“#command# exited with code 1”。

有一些我尝试过的 VS post/pre-build 命令的例子:
调用“projdir\test.bat”
调用 projdir\test.bat
“projdir\test.bat”
projdir\test.bat
...我尝试将 projdir 作为“$(ProjectPath)”和手动路径。

我将输出设置为详细并发现以下内容:
命令“C:\Users\Traubenfuchs\AppData\Local\Temp”写入不正确或找不到。 (该文件夹实际上存在,但我不知道它想要做什么。)
当我在构建前/构建后放置一个 xcopy 命令时,也会发生同样的事情。

有谁知道我做错了什么?

【问题讨论】:

  • 以管理员身份运行解决了我的问题

标签: visual-studio batch-file powershell


【解决方案1】:

最近遇到了类似的问题。

关于您的“hello world”构建后活动: 尝试直接调用powershell

powershell -command "write-output 'hello world'; exit 0"

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

我的预构建事件如下所示:

powershell -file scriptPath.ps1

我的 scriptPath.ps1 看起来像:

<my epic powershell code>
...
exit 0

请注意,最后没有“exit 0”,我从脚本中收到了返回码 1。

【讨论】:

    【解决方案2】:

    我们遇到此问题是因为在域 GPO 中设置了“软件限制策略”。似乎 pre 和 post 构建在 temp 文件夹中创建了一个 .cmd 批处理文件。以下是日志记录向我展示的内容:

    cmd.exe (PID = 8456) 已识别 C:\Users\brian\AppData\Local\Temp\tmp733425d2c0604973a90a0a175c13353e.exec.cmd 由于不允许使用默认规则,Guid = {11015445-d282-4f86-96a2-9e485f593302}

    为解决此问题,我们修改了控制 SRP 的 GPO,使其不包含 .cmd 文件。毕竟,SRP 的目标是阻止可执行恶意软件,而不是批处理文件。因此,我可能会受到一些安全反击。希望有人知道解决此问题的更好方法。

    【讨论】:

    • 你是如何记录这个的?
    • @briddums 我相信我这样做了:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers\LogFileName="C:\logs\srp.log"
    • 很遗憾,我无法修改该政策,并且此处提供的其他选项均无效...
    【解决方案3】:

    一个可能的问题是您必须使用$(ProjectDir) 而不是$(ProjectPath)

    当你使用$(ProjectPath)时,实际上是:"C:\Users\....\Project\MyProject.csproj"

    相对于$(ProjectDir),即:"C:\Users\....\Project\"

    请注意,第一个版本实际上指向您的项目解决方案文件...这将导致一切失败。

    另一个是$(ProjectDir) 自动将尾部斜杠添加到路径中。即"$(ProjectDir)\test.bat" 实际上会转换为:"C:\Users\....\Project\\test.bat"

    您还必须确保将所有文件路径用双引号括起来

    所以正确的调用应该是这样的:

    call "$(ProjectDir)test.bat"
    

    要检查的其他事项是确保执行脚本的目录是正确的。请参阅:visual studio 2012, postbuild event, bat file not creating new file (not executing)

    您是否查看过 * 中的建议? Post Build exited with code 1


    编辑

    试试这个:

    echo Hello World
    @exit 0
    

    您需要以@exit 0 结束任何命令,否则它认为它没有正确完成


    编辑 2

    为什么我们使用@exit 0 而不是exit 0? @Sunny 对 At 符号有很好的解释 - @here

    @ 符号告诉命令处理器不要那么冗长;只 显示命令的输出而不显示它正在执行或 与执行相关的任何提示。使用时,它是前置的 到命令的开头,不必留空格 在“@”和命令之间。

    基本上如果你call xyz.bat 默认情况下.bat 文件中的每个命令都会与命令的实际输出一起回显。例如:

    test.bat

    echo Hello World
    exit 0
    

    将输出:

    C:\>call test.bat
    
    C:\>echo Hello World
    Hello World
    
    C:\>exit 0
    
    C:\>
    

    当我们在命令前面添加@ 时,我们只得到命令本身的输出。

    test2.bat

    @echo Hello World
    @exit 0
    

    将输出:

    C:\>call c.bat
    Hello World
    
    C:\>
    

    @echo off 也是一种为脚本的其余部分关闭此功能的方法。我们通常这样做只是为了使日志更易于阅读,因为命令的文本会混淆日志输出。

    【讨论】:

    • 我尝试了所有这些但没有帮助。看看我贴的图,我连echo都叫不出来。我认为我从根本上做错了什么。
    • 尝试将@exit 0 添加到命令的末尾(请参阅编辑),否则它会一直认为出现问题。
    • 不走运:命令“echo Hello World @exit 0”以代码 1 退出。C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets 1063 5 SOLUTIONNAME
    • 我认为你有一个错字:另一个是 $(ProjectDir) 自动将尾部斜杠添加到路径中。即 "$(ProjectDir)\test.bat" 实际上会转换为: "C:\Users....\Project\test.bat 应该是 另一个是 $(ProjectDir) 自动添加路径的尾部斜杠。即“$(ProjectDir)\\test.bat”实际上将转换为:“C:\Users....\Project\test.bat”(双结尾“\”) .
    • ECHO|SET /P="My final line without a CR"&gt;&gt; "$(ProjectDir)myfile.vb" @EXIT 0 为我工作。
    最近更新 更多