开发者

How do I fix my "self-deleting" .exe from deleting itself early?

For the sake of testing and personal proof of concept, I have a .exe file that only outputs a simple string and then calls a system pause (literally system("pause") in C++).

I have a simple Python script I'm testing on a Window开发者_运维百科s XP VM that does these operations when messing up:

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)

Obviously, those commands all work fine alone on the command line, why don't they work fine when called through Python?

I receive this pop-up error message:

blank.txt:ads.exe has encountered a problem and needs to close. We are sorry for the inconvenience.

If you were in the middle of something, the information you were working on might be lost.

The file is indeed deleted, also. It seems that the system pause is just crushed by the delete command, when I expect the .exe to pop up, wait for me to push enter, and then the script will continue and delete the file.


Given the symptoms, my understanding is that you can only safely delete an executable in this particular setting (Windows XP, perhaps at a particular patch level, when the executable is from an alternate stream) once this executable has finished initializing. If you delete an executable while it's loading, the program crashes.

When you type these commands at a prompt, some time elapses between running start c:\blank.txt:ads.exe and del c:\blank.txt, giving the program enough time to finish loading. When you're running them from a script, the interval between the two is a lot shorter (start branches off a new process, and the new program's initialization happens asynchronously). There's race condition between the initialization and the deletion; which one wins depends on how soon the deletion is performed.

Try experimenting with a delay before deleting the file:

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)


What happens is that each subprocess.call(..., shell=True) is immediately returning because they're just telling the shell to execute a command. On the commandline, calling an exe to run using the start command will still immediately return even though the exe has not terminated. The start immediately returned and it needs to be told to wait:

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)


The windows shell start command will launch the program in a new shell and then just continue. To wait for it to complete use call:

subprocess.call(r'call c:\blank.txt:ads.exe', shell=True)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜