写入文件和运行文件有时会起作用,大多数只是第一个

时间:2015-01-11 15:54:17

标签: python multithreading subprocess temporary-files

此代码大多数时候会产生WindowsError,很少(通常第一次运行时)很少。

""" Running hexlified codes from codefiles module prepared previously """

import tempfile
import subprocess
import threading
import os

import codefiles

if __name__ == '__main__':
    for ind, c in enumerate(codefiles.exes):
        fn = tempfile.mktemp() + '.exe'
        # for some reason hexlified code is sometimes odd length and one nibble
        if len(c) & 1:
            c += '0'
        c = c.decode('hex')
        with open(fn, 'wb') as f:
            f.write(c)

        threading.Thread(target=lambda:subprocess.Popen("", executable=fn)).start()

""" One time works, one time WindowsError 32
>>> 
132096 c:\docume~1\admin\locals~1\temp\tmpkhhxxo.exe
991232 c:\docume~1\admin\locals~1\temp\tmp9ow6zz.exe
>>> ================================ RESTART ================================
>>> 
132096 c:\docume~1\admin\locals~1\temp\tmp3hb0cf.exe
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Documents and Settings\Admin\My Documents\Google Drive\Python\Tools\runner.pyw", line 18, in <lambda>
    threading.Thread(target=lambda:subprocess.Popen("", executable=fn)).start()
  File "C:\Python27\lib\subprocess.py", line 710, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 958, in _execute_child
    startupinfo)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process
991232 c:\docume~1\admin\locals~1\temp\tmpnkfuon.exe

>>> 
"""

使用此脚本完成Hexlification,它有时似乎产生奇数个半字节,看起来也很奇怪。

# bootstrapper for running hexlified executables,
# hexlification can be done by running this file directly or calling function make
# running can be done by run function in runner module, which imports the code,
# runs them from temporary files

import os

modulename = 'codefiles.py'

def code_file_names(d='.', ext='.exe'):
    return [n for n in os.listdir(d)
                            if n.lower().endswith(ext)]

def make():
    codes = code_file_names(os.curdir)
    with open(modulename, 'a') as f:
        f.write('exes = (')
        hex_codes = [open(n, 'rb').read().encode('hex') for n in codes]
        assert all(len(c) & 1 == 0 for c in hex_codes)
        print len(hex_codes),map(len, hex_codes)
        hex_codes = [repr(c) for c in hex_codes]
        f.write(',\n'.join(hex_codes))
        f.write(')\n')


if __name__ == '__main__':
    import make_exe

    # prepare hexlified exes for exes  in directory if codefiles not prepared
    if modulename not in os.listdir('.'):
        try:
            os.remove(modulename)
        except:
            pass   
        make()

    # prepare script for py2_exe to execute the scripts by run from runner
    make_exe.py2_exe('runner.pyw', 'tools/dvd.ico')        

在Martelli先生的建议之后,我得到了错误消失,但仍然没有预料到结果。

我传入新版本的代码创建exe文件(如果存在)(在新创建例程中保存文件名)。它在创建文件时启动两个代码(两个hexlified代码),但之后会发送第一个代码的多个副本。

1 个答案:

答案 0 :(得分:2)

tempfile.mktemp(),除了由于其安全性问题而多年被弃用之外,仅在一次程序运行中保证唯一名称,因为,每https://docs.python.org/2/library/tempfile.html#tempfile.mktemp,&#34;该模块使用一个全局变量告诉它如何构造一个临时名称&#34;。因此,在第二次运行时,正如非常明确的错误消息告诉您的那样,&#34;进程无法访问该文件,因为它正被另一个进程使用&#34; (具体来说,该过程由前一次运行开始,即您无法重写当前正在某些过程中运行的.exe。)

修复方法是确保每次运行都使用自己唯一的临时文件目录。请参阅https://docs.python.org/2/library/tempfile.html#tempfile.mkdtemp上的mkdtemp。如何最终清理这些临时目录是一个不同的问题,因为只要任何进程在这样的目录中运行.exe文件,就无法完成 - 你可能需要一个单独的&#34;清理脚本&#34;为此目的尽其所能,定期运行(例如在Unix中我使用cron)和一个存储库(例如一个小sqlite数据库,甚至只是一个文件)来记录哪个在以前的运行中创建的临时目录仍然存在,需要清除(捕获他们无法清理时看到的异常,以便将来重试)。