为什么在Visual Studio中所有的预构建或后构建事件都以退出码1失败?

13

我的目标是在解决方案A的bin文件夹中的复制一个.exe文件到另一个解决方案B的资源文件夹中,该操作需要在解决方案A的后生成事件中完成。
我创建了必要的xcopy命令,并在powershell中尝试了一下:它完美地运行了。
但每当我在VS中添加任何命令到操作中时,构建就会失败并出现“#command# exited with code 1”的错误提示,其中#command#是例如xcopy命令。
我尝试以管理员身份运行VS,还尝试运行包含“@echo off @exit 0”命令的.bat文件,但这些也会导致“#command# exited with code 1”的错误提示。

以下是我在VS的后/前生成命令中尝试过的示例:
call "projdir\test.bat"
call projdir\test.bat
"projdir\test.bat"
projdir\test.bat
... 我尝试将projdir作为“$(ProjectPath)”和手动路径使用。

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

有谁知道我做错了什么吗?

enter image description here


以管理员身份运行解决了我的问题。 - Sreekumar P
3个回答

7

最近我遇到了类似的问题。

关于您的“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的提示。

7
我们遇到了这个问题,是因为在域GPO中设置了“软件限制策略”。似乎预构建和后构建会在临时文件夹中创建一个.cmd批处理文件。以下是日志内容:

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

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

1
你是如何记录这个的? - briddums
@briddums 我相信我已经完成了这个任务:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers\LogFileName="C:\logs\srp.log" - Brain2000
很不幸,我无法修改该策略,这里提供的其他选项也都不可行... - Johnny

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"

请确保脚本执行的目录正确。参见 StackOverflow 上的这个链接:visual studio 2012, postbuild event, bat file not creating new file (not executing)
您是否查看了这个 StackOverflow 上的建议?Post Build exited with code 1
编辑
请尝试这个:
echo Hello World
@exit 0

您需要在任何命令后面添加@exit 0,否则它会认为没有正常完成。

编辑2

为什么我们使用@exit 0而不是exit 0?@Sunny在这里提供了一个很好的解释 - @ 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也是关闭脚本中此功能的一种方式。我们通常这样做只是为了使日志更易于阅读,因为命令的文本会使日志输出变得混乱。


1
尝试在命令的末尾添加@exit 0(参见编辑),否则它将始终认为出现了错误。 - HAL9256
1
没有运气:命令“echo Hello World @exit 0”以代码1退出。C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets 1063 5 SOLUTIONNAME - ASA
我认为你打错了:另一个问题是$(ProjectDir)会自动在路径后面添加斜杠。例如,"$(ProjectDir)\test.bat"实际上会被转换为:"C:\Users....\Project\test.bat" 应该改为_另一个问题是$(ProjectDir)会自动在路径后面添加斜杠。例如,"$(ProjectDir)\test.bat"实际上会被转换为:"C:\Users....\Project\test.bat"_(双反斜杠)。 - SteveCinq
ECHO|SET /P="My final line without a CR">> "$(ProjectDir)myfile.vb" @EXIT 0 对我有用。 - SteveCinq
1
@Waldron。好问题。@exit 0exit 0都是一样的,唯一的区别在于生成的输出(请参见上面的编辑2)。 - HAL9256
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接