简体   繁体   English

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

[英]Writing to file and running the files sometimes works, mostly only first one

This code produces WindowsError most times, rarely (like often first time it is run) not. 这段代码在大多数情况下会产生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 is done with this script, and it sometimes seems to produce odd number of nibbles which seems also odd. 六边形化是使用此脚本完成的,有时似乎会产生奇数个半字节,这似乎也很奇怪。

# 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')        

After Mr. Martelli's suggestion, I got the error disappear, but still not expected result. 在Martelli先生的建议之后,我的错误消失了,但仍然没有得到预期的结果。

I pass in new version of code the creation of exe file if it exists (saved file names in new creation routine). 我通过新版本的代码来创建exe文件(如果存在)(在新的创建例程中保存了文件名)。 It launches both codes (two hexlified codes) when creating the files, but multiple copies of first code afterwards. 创建文件时,它会同时启动两个代码(两个十六进制代码),但之后会同时复制多个第一个代码。

tempfile.mktemp() , besides being deprecated since many years because of its security problems, guarantees unique names only within a single run of a program, since, per https://docs.python.org/2/library/tempfile.html#tempfile.mktemp , "The module uses a global variable that tell it how to construct a temporary name". tempfile.mktemp()除了由于其安全性问题已被弃用多年之外,还保证仅在程序的一次运行中使用唯一名称,因为根据https://docs.python.org/2/library/tempfile.html #tempfile.mktemp ,“该模块使用一个全局变量来告诉它如何构造一个临时名称”。 So on the second run, as the very clear error message tells you, "The process cannot access the file because it is being used by another process" (specifically, the process started by the previous run, ie you cannot re-write an .exe that's currently running in some process). 因此,在第二次运行时,很清楚的错误消息告诉您,“该进程无法访问该文件,因为该文件正在被另一个进程使用”(特别是,该进程是由上一次运行启动的,即您无法重写.exe ,目前正在某些进程中运行)。

The fix is to make sure each run uses its own unique directory for temporary files. 解决方法是确保每次运行都将其自己的唯一目录用于临时文件。 See mkdtemp at https://docs.python.org/2/library/tempfile.html#tempfile.mkdtemp . 请参阅https://docs.python.org/2/library/tempfile.html#tempfile.mkdtemp上的 mkdtemp How to eventually clean up those temporary directories is a different issue since that can't be done as long as any process is running an .exe file within such a directory -- you'll probably need a separate "clean-up script" that does what it can for the purpose, run periodically (eg in Unix I'd use cron ) and a repository (eg a small sqlite DB, or even just a file) to record which of the temporary directories created in previous runs still exist and need to be cleared up (catching the exceptions seen when they can't get cleaned up yet, so as to retry in the future). 最终如何清理这些临时目录是一个不同的问题,因为只要任何进程正在该目录中运行.exe文件,就无法做到这一点-您可能需要一个单独的“清理脚本”尽其所能,定期运行(例如,在Unix中,我将使用cron )和存储库(例如,小型sqlite DB甚至只是一个文件)运行,以记录先前运行中创建的哪些临时目录仍然存在,并且需要清除(捕获尚无法清除的异常,以便将来重试)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM