SignTool.exe错误后,Visual Studio中的PostBuild事件失败 [英] PostBuild Event fails in Visual Studio after SignTool.exe error

查看:354
本文介绍了SignTool.exe错误后,Visual Studio中的PostBuild事件失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在Visual Studio 2010中有一个项目,该项目在生成后事件中运行批处理文件.该批处理从Microsoft SDK调用signtool.exe,以对二进制文件进行签名和时间戳.

We have a project in Visual Studio 2010 that runs a batch file in the post-build event. That batch calls to signtool.exe from Microsoft SDK to sign and timestamp the binary.

时间戳服务器(我们使用 http://timestamp.verisign.com/scripts/timstamp. dll ),但由于某种原因往往不可靠,有时会失败.这导致构建失败.

Timestamp servers (we use http://timestamp.verisign.com/scripts/timstamp.dll), however, tend to be unreliable for some reason, failing sometimes. This caused build to fail.

然后我们实施了一个更高级的批处理脚本(基于代码),拆分签名和时间戳,并在失败的情况下允许重试时间戳操作.

We implemented a more advanced batch script then (based on this code), splitting signing and timestamping, and allowing to retry the timestamp operation, if it failed.

这是批处理脚本(signfile.bat)的简化版本:

Here is a simplified version of the batch script (signfile.bat):

@echo off

REM sign the file...
signtool.exe /f Authenticode.pfx /p PASS %1

if %errorlevel% neq 0 exit /b %errorlevel%

set timestamp_server=http://timestamp.verisign.com/scripts/timstamp.dll

for /L %%a in (1,1,10) do (

    REM try to timestamp the file...
    signtool.exe timestamp /t %timestamp_server% %1

    if errorlevel 0 if not errorlevel 1 GOTO succeeded

    REM wait 2 seconds...
    ping -n 2 127.0.0.1 > nul
)

REM return an error code...
echo signfile.bat exit code is 1.
exit /b 1

:succeeded
REM return a successful code...
echo signfile.bat exit code is 0.
exit /b 0

构建后事件代码如下:

signfile.bat "$(OutDir)$(TargetName)$(TargetExt)"

因此,如果时间戳失败,它将以2秒的间隔重试10次.

So, if the timestamping fails, it retries 10 times with 2-seconds intervals.

但是,我们观察到的是,如果时间戳从第一次尝试开始就很好,那么一切都很好.但是,如果第一次尝试失败,那么即使时间戳记在下一次尝试中成功,整个构建后事件也会以代码-1失败.

But, what we observed was, if the timestamping went fine from the first attempt, everything was OK. However, if the first attempt failed, then the whole post-build event failed with code -1, even though the timestamping succeeded on the next try.

1>------ Build started: Project: myproject, Configuration: NonOptimized x64 ------
1>  Done Adding Additional Store
1>  Successfully signed: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>  
1>EXEC : SignTool error : The specified timestamp server either could not be reached
1>  or returned an invalid response.
1>    This may happen if you specify an RFC 3161 timestamp URL but used
1>    the /t option or you specified a legacy Authenticode timestamp URL
1>    but used the /tr option.
1>EXEC : SignTool error : An error occurred while attempting to timestamp: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>  
1>  
1>  Number of errors: 1
1>  
1>  Successfully timestamped: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>  
1>  signfile.bat exit code is 0.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: The command "signfile.bat "E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll"
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :VCEnd" exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

因此,如您所见,即使从signfile.bat返回的错误代码为0,Visual Studio仍认为它为-1并且使事件失败.

So, as you can see, even though the error code returned from signfile.bat is 0, Visual Studio thinks it is -1 and fails the event.

所有清除错误标志的尝试(例如在各处添加ver>nul或在末尾添加exit 0(一定在signfile.bat之前添加"call"))均无济于事,因为它看起来像Visual Studio不仅检查错误级别,还检查其他内容.实际上,批处理以及signfile.bat在出现错误的情况下仅返回0或1,但不会返回-1.而且,如果signtool.exe一次返回错误,则似乎无法说服Visual Studio不要使生成后事件失败.

All attempts to clear the error flag, like adding ver>nul here and there, or adding exit 0 in the end (certainly with adding "call" before signfile.bat) didn't help since it seemed like Visual Studio checked not just for errorlevel but also for something else. In fact, the batch as well as signfile.bat only return 0 or 1 in case of error, but not -1. And if signtool.exe returns an error once, it seems like there is no way to convince Visual Studio not to fail the post-build event.

推荐答案

在花了很多时间进行实验和搜索之后,发现了一个

After spending much time experimenting and searching, found an article, mentioned here in a comment. It looks like Visual Studio scans the output, searching for some special keywords. Signtool.exe outputs among the other EXEC : SignTool error : An error occurred, which seems like enough to alert Visual Studio that there was an error.

因此,提出的解决方案是将输出和错误流重定向为2>nul 1>nul到nul.错误级别仍将被设置,因此您将能够确定是否发生了错误.但是您可能必须打印一些额外的消息才能查看状态:

So, the solution proposed was to redirect output and error streams to nul as 2>nul 1>nul. Errorlevel will still be set, so you will be able to figure out if error occured. But you may have to print some extra messages to see the status:

REM try to timestamp the file...
signtool.exe timestamp /t %timestamp_server% %1 2>nul 1>nul

if errorlevel 0 if not errorlevel 1 (
    echo Successfully timestamped: %1
    GOTO succeeded
)
echo Timestamping failed for %1

现在Visual Studio很高兴:

Now Visual Studio is happy:

1>------ Build started: Project: myproject, Configuration: NonOptimized x64 ------
1>  Done Adding Additional Store
1>  Successfully signed: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>  
1>  Timestamping failed for "E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll"
1>  Successfully timestamped: "E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll"
1>  signfile.bat exit code is 0.
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

实际上,只需添加2>nul就可以修复它.错误流仍将被打印:Number of errors: 1,但这不会引起问题.

In fact, just adding 2>nul would be enough to fix it. Error stream will still be printed: Number of errors: 1, but it does not cause a problem.

这篇关于SignTool.exe错误后,Visual Studio中的PostBuild事件失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆