在Windows 8,Python 3.3下运行,我正在产生3个应该一个接一个地运行的进程:第一个,签署可执行文件,第二个,使用Inno Setup构建一个工具包(它涉及第一步的可执行文件),以及最后,使用第二步的输出进行签名。但是,从时间开始,我得到的似乎是竞争条件,其中签名工具抱怨它无法签署可执行文件。在我看来,第二个进程不会以某种方式(或操作系统)释放文件句柄...查找错误代码后,虽然应该这样做(我正在使用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(文件,os.W_OK)。
我没有运行防病毒软件,也无法想到任何可能影响签名过程的内容。
答案 0 :(得分:0)
事实证明我正在寻找错误方向的罪魁祸首。
经过更多的研究 - 并且没有找到锁定我的文件的进程(使用Process Explorer,直接从我的脚本中使用Handle工具,LockHunter) - 我找到了足够的轶事证据来确定Windows Defender是“罪犯” 。显然,它在Windows 8中的集成非常好,您可以完全忘记它的实时保护模块在后台运行。有时,一旦我的文件可执行文件被创建,它就会将其锁定一段无限的时间,这足以让我后来尝试签署它...失败。
我为我最初的错误推定道歉。