在 Windows 8、Python 3.3 下运行,我生成了 3 个进程,它们应该一个接一个地运行:首先,签署一个可执行文件,其次,使用 Inno Setup 构建一个工具包(它涉及第一步中的可执行文件),最后,使用第二步的输出来签名。但是,从 ti 时间开始,我得到了似乎是一种竞争条件,其中签名工具抱怨它无法签署可执行文件。在我看来,第二个进程并没有以某种方式(或操作系统)释放文件句柄......在查找错误代码之后,虽然它应该完成(我正在使用 process.communicate() 来确保这一点) . 我也怀疑存在竞争条件,因为使用 time.sleep() 似乎可以解决问题。
第二个进程是否有可能以某种方式分离并在后台运行?但如果是这样,为什么我仍然可以始终在我的日志文件中看到正确登录的操作(例如,第一次唱歌输出、构建、第二次签名(无论它是成功还是不成功))?我从通信中获得输出的事实不应该意味着所有资源(包括文件句柄)都已被释放吗?这是代码:
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(file, os.W_OK) 。
我没有运行防病毒软件,也想不出其他任何可能干扰签名过程的东西。