子进程似乎结束了,但是没有释放文件句柄

时间:2013-03-22 13:41:34

标签: python-3.x subprocess signing

在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)。

我没有运行防病毒软件,也无法想到任何可能影响签名过程的内容。

1 个答案:

答案 0 :(得分:0)

事实证明我正在寻找错误方向的罪魁祸首。

经过更多的研究 - 并且没有找到锁定我的文件的进程(使用Process Explorer,直接从我的脚本中使用Handle工具,LockHunter) - 我找到了足够的轶事证据来确定Windows Defender是“罪犯” 。显然,它在Windows 8中的集成非常好,您可以完全忘记它的实时保护模块在后台运行。有时,一旦我的文件可执行文件被创建,它就会将其锁定一段无限的时间,这足以让我后来尝试签署它...失败。

我为我最初的错误推定道歉。