如何修复我的“自删除” .exe 提前删除的问题?
为了测试和个人验证,我有一个.exe文件,它只输出一个简单的字符串,然后调用系统暂停(在C++中就是system("pause")
)。
我在一个Windows XP虚拟机上测试一个简单的Python脚本,当出现问题时,它会执行这些操作:
subprocess.call(r'echo Nothing special. > c:\blank.txt', shell=True)
subprocess.call(r'type pause.exe > c:\blank.txt:ads.exe', shell=True)
subprocess.call(r'start c:\blank.txt:ads.exe', shell=True)
subprocess.call(r'del c:\blank.txt', shell=True)
显然,这些命令在命令行中单独运行都没问题,为什么通过Python调用时就不行呢?
我收到这个弹出错误信息:
blank.txt:ads.exe 遇到了一个问题,需要关闭。我们对此造成的不便表示歉意。
如果你正在进行某项工作,可能会丢失你正在处理的信息。
文件确实被删除了。看起来是删除命令把系统暂停给压制了,我原本期待.exe文件会弹出来,等我按下回车后再继续执行脚本并删除文件。
3 个回答
Windows的命令行中,start
命令会在一个新的窗口中启动程序,然后继续执行后面的命令。如果你想等这个程序运行完再继续,可以使用call
命令:
subprocess.call(r'call c:\blank.txt:ads.exe', shell=True)
发生的情况是,每次使用 subprocess.call(..., shell=True)
时,它都会立即返回,因为它只是告诉系统去执行一个命令。在命令行中,使用 start
命令来运行一个可执行文件(exe)时,虽然这个可执行文件还没有结束,但 start
也会立刻返回。也就是说,start
命令会立刻完成,但如果你想让它等着可执行文件结束,就需要特别告诉它去等待:
subprocess.call(r'echo Nothing special. > c:\blank.txt', shell=True)
subprocess.call(r'type pause.exe > c:\blank.txt:ads.exe', shell=True)
subprocess.call(r'start /wait c:\blank.txt:ads.exe', shell=True)
subprocess.call(r'del c:\blank.txt', shell=True)
根据这些症状,我的理解是,在这种特定的环境下(比如Windows XP,可能是某个特定的补丁版本,并且这个可执行文件来自一个备用流),你只能在这个可执行文件完成初始化后安全地删除它。如果你在它加载的时候删除这个可执行文件,程序就会崩溃。
当你在命令提示符下输入这些命令时,从运行 start c:\blank.txt:ads.exe
到 del c:\blank.txt
之间会有一段时间,这段时间足够让程序完成加载。而如果你是通过脚本来运行这些命令,两个命令之间的时间间隔就会短很多(start
会启动一个新进程,而新程序的初始化是异步进行的)。这就造成了初始化和删除之间的竞争条件;哪个先完成就决定了结果,这取决于你删除命令执行得有多快。
你可以尝试在删除文件之前加个延迟:
import subprocess, time
subprocess.call(r'echo Nothing special. > c:\blank.txt', shell=True)
subprocess.call(r'type pause.exe > c:\blank.txt:ads.exe', shell=True)
subprocess.call(r'start c:\blank.txt:ads.exe', shell=True)
time.sleep(42) # 42 seconds is overkill, but the delay isn't predictable
subprocess.call(r'del c:\blank.txt', shell=True)