2013-03-22 2 views
1

Запуск под 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), прежде чем пытаться выполнить последнее подписание.

Я не запускаю антивирус и не могу придумать ничего, что могло бы помешать процессу подписания.

+1

Использование '' '' '' '' выполняет '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

+0

Спасибо, Eryksun. Я обязательно проверю ваше первое предложение; это имеет смысл (и в этом контексте я обнаружил, что у Пихтона тоже есть сборщик мусора ...). Для этого потребуется некоторое расширенное тестирование, но я вернусь и сообщите об этом. –

+0

Я не уверен в другом вопросе; вы бы так любезны перефразировать его? Я не хочу предполагать, может быть, я чего-то не хватает. Спасибо за ваше время. –

ответ

0

Оказалось, что я искал виновника в неправильном направлении.

После дополнительных исследований - и не выясняя, какой процесс был заблокирован моим файлом (используя Process Explorer, инструмент Handle непосредственно из моего скрипта, LockHunter) - я нашел достаточно анекдотических доказательств, чтобы убедиться, что Защитник Windows был «нарушителем» ». По-видимому, он настолько хорошо интегрирован в Windows 8, что вы можете полностью забыть, что его модуль защиты в реальном времени работает в фоновом режиме. Иногда, как только мой исполняемый файл был создан, он блокировал бы его на бесконечно малое количество времени, достаточно для моей последующей попытки подписать его ... чтобы потерпеть неудачу.

Прошу прощения за мою первоначальную, ложную презумпцию.

Смежные вопросы