У нас есть проект в 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.