Событие PostBuild завершилось с ошибкой в Visual Studio после ошибки SignTool.exe
У нас есть проект в Visual Studio 2010, который запускает командный файл в событии после сборки. Эта партия вызывает signtool.exe из Microsoft SDK для подписания и отметки времени в двоичном формате.
Серверы Timestamp (мы используем http://timestamp.verisign.com/scripts/timstamp.dll), однако по какой-то причине они ненадежны, иногда сбой. Это привело к сбою сборки.
Мы реализовали более продвинутый пакет script, затем (на основе этого кода), разделив подпись и отметку времени и позволив повторить операцию метки времени, если она не удалась.
Вот упрощенная версия пакета 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)"
Итак, если временная отметка не удалась, она повторяет 10 раз с интервалом в 2 секунды.
Но, что мы наблюдали, было, если временная отметка прошла с первой попытки, все было в порядке. Однако, если первая попытка не удалась, то событие post-build завершилось с кодом -1, даже если при попытке повторить эту попытку удалось выполнить следующую попытку.
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 и не удается выполнить событие.
Все попытки очистить флаг ошибки, например добавление ver>nul
здесь и там, или добавление exit 0
в конце (конечно, с добавлением "вызова" перед signfile.bat) не помогло, так как это казалось Visual Studio проверен не только на уровень ошибок, но и на что-то еще. Фактически, пакет, а также signfile.bat возвращают только 0 или 1 в случае ошибки, но не -1. И если signtool.exe возвращает ошибку один раз, кажется, что нет возможности убедить Visual Studio не вызывать событие post-build.
Ответы
Ответ 1
Проведя много времени на экспериментирование и поиск, найдите статью , упомянутую здесь в комментарии. Похоже, Visual Studio сканирует выход, ищет некоторые специальные ключевые слова. Signtool.exe выводит среди других EXEC : SignTool error : An error occurred
, которые кажутся достаточно, чтобы предупредить Visual Studio о том, что произошла ошибка.
Итак, предлагаемое решение состояло в том, чтобы перенаправить выходные и потоки ошибок в nul как 2>nul 1>nul
. Уровень ошибок по-прежнему будет установлен, поэтому вы сможете выяснить, произошла ли ошибка. Но вам может потребоваться распечатать дополнительные сообщения, чтобы увидеть статус:
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 довольна:
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
, но это не вызывает проблемы.