Запуск под Windows 8, Python 3.3, я создаю 3 процесса, которые должны запускаться один за другим: во-первых, подписание исполняемого файла, во-вторых, создание набора с помощью Inno Setup (он включает исполняемый файл с 1-го шага) и, наконец, используя вывод второго шага для его подписания. Однако, с момента времени, я получаю то, что кажется условием гонки, в котором инструмент подписи жалуется, что он не может подписать исполняемый файл. Мне кажется, что второй процесс не выдает дескриптор файла каким-то образом (или ОС) ... после поиска кода ошибки, хотя это должно быть сделано (я использую process.communicate(), чтобы убедиться в этом) , Я также подозреваю состояние гонки, поскольку, используя time.sleep(), похоже, решает проблему.Подпроцесс, кажется, заканчивается, но не освобождает дескриптор файла
Возможно ли, что второй процесс каким-то образом отделяется и работает в фоновом режиме? Но если это так, то почему я все еще всегда вижу, что операции, зарегистрированные в моем журнале, выполняются правильно (например, 1-й выпуск, сборка, 2-ое подписание (независимо от того, успешна или неуспешна)? Не должен ли тот факт, что я получаю сообщение от общения, означает, что все ресурсы (включая дескрипторы файлов) были выпущены? Вот код:
def do_build():
'''
Prepare the kit.
'''
global kit_file
kit_file = ''.join([OUTPUT_FILENAME, '_', version]) # do not add '.exe', as Inno does it during build
DESCR = 'Execute Build'
logf.write(BEGIN + DESCR + SEP2)
def run_command(c, ex):
with subprocess.Popen(c, stdout = subprocess.PIPE, stderr = subprocess.PIPE, executable = ex) as proc:
stdout_data, stderr_data = proc.communicate()
logf.write(str(stdout_data, 'cp1252'))
if proc.returncode != 0: # log errors if needed
logf.write(str(stderr_data, 'cp1252'))
sys.exit()
sign_exe = [SIGNCODE, '-cn', TTT, '-n', KIT_TYPE2.upper(), '-i', URL, '-t', TSURL]
sign_kit = sign_exe[:] # make copy
sign_exe.append(os.sep.join([PDIR, DEPLOYMENT, EXECUTABLE])) # sign the executable
run_command(sign_exe, os.sep.join([PDIR, SIGNCODE]))
compile = [ISCC, ''.join(['/O', OUTPUT_DIR]), ''.join(['/F', kit_file]), os.sep.join([PDIR, ISS_FILE])] # compile using the ISS script
run_command(compile, os.sep.join([ISSC_PATH, ISCC]))
# time.sleep(something) here seems to save the day...
sign_kit.append(os.sep.join([PDIR, ''.join([kit_file, '.exe'])])) # sign the kit, don't forget '.exe'
run_command(sign_kit, os.sep.join([PDIR, SIGNCODE]))
logf.write(END + DESCR + SEP2)
Я использую InnoSetup 5, инструмент командной строки, iscc.exe, FWIW.
Любые объяснения по этому вопросу? Единственное, что я вижу, это использовать os.access (файл, os.W_OK), прежде чем пытаться выполнить последнее подписание.
Я не запускаю антивирус и не могу придумать ничего, что могло бы помешать процессу подписания.
Использование '' '' '' '' выполняет 'wait' в процессе, но его [' Handle'] (http://hg.python.org/cpython/file/bd8afb90ebf2/Lib/subprocess.py#l427) (Lib/subprocess.py) закрывается только GC через '__del__'. Возможно, это вопрос времени. Попробуйте руководство 'proc._handle.Close()' в конце 'run_command', после' with'. – eryksun
Спасибо, Eryksun. Я обязательно проверю ваше первое предложение; это имеет смысл (и в этом контексте я обнаружил, что у Пихтона тоже есть сборщик мусора ...). Для этого потребуется некоторое расширенное тестирование, но я вернусь и сообщите об этом. –
Я не уверен в другом вопросе; вы бы так любезны перефразировать его? Я не хочу предполагать, может быть, я чего-то не хватает. Спасибо за ваше время. –