处理Windows下的子进程崩溃
我在Windows命令提示符下运行一个Python脚本。这个脚本调用了下面的函数,它的作用是把MP3文件转换成WAVE文件,使用的是LAME这个工具。
def convert_mp3_to_wav(input_filename, output_filename):
"""
converts the incoming mp3 file to wave file
"""
if not os.path.exists(input_filename):
raise AudioProcessingException, "file %s does not exist" % input_filename
command = ["lame", "--silent", "--decode", input_filename, output_filename]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = process.communicate()
if process.returncode != 0 or not os.path.exists(output_filename):
raise AudioProcessingException, stdout
return output_filename
可惜的是,LAME在处理某些MP3文件时总是崩溃,真是名副其实。每当崩溃时,Windows会弹出一个“你的程序已经崩溃”的对话框,这会导致我的脚本停止运行。等我关闭这个对话框后,才会出现一个AudioProcessingException的错误。
我希望能让脚本直接抛出这个错误,然后继续处理下一个MP3文件,而不是每次都要去告诉Windows别吵了。
有没有什么办法可以解决这个问题?最好是通过修改脚本,而不是用Unix来运行它。
我使用的是Windows 7和Python 2.6。
2 个回答
0
我用 creationflags=subprocess.CREATE_NO_WINDOW
这个设置可以正常运行。即使应用程序崩溃,仍然会返回正确的应用输出。
26
经过一番搜索,我偶然发现了这个链接:http://www.activestate.com/blog/2007/11/supressing-windows-error-report-messagebox-subprocess-and-ctypes
这个方法需要稍微调整一下,但下面的方法现在可以避免那些烦人的Windows提示信息了 :) 记得在subprocess.Popen中也要加上creationflags=subprocess_flags哦。
def convert_mp3_to_wav(input_filename, output_filename):
if sys.platform.startswith("win"):
# Don't display the Windows GPF dialog if the invoked program dies.
# See comp.os.ms-windows.programmer.win32
# How to suppress crash notification dialog?, Jan 14,2004 -
# Raymond Chen's response [1]
import ctypes
SEM_NOGPFAULTERRORBOX = 0x0002 # From MSDN
ctypes.windll.kernel32.SetErrorMode(SEM_NOGPFAULTERRORBOX);
subprocess_flags = 0x8000000 #win32con.CREATE_NO_WINDOW?
else:
subprocess_flags = 0
"""
converts the incoming mp3 file to wave file
"""
if not os.path.exists(input_filename):
raise AudioProcessingException, "file %s does not exist" % input_filename
#exec("lame {$tmpname}_o.mp3 -f {$tmpname}.mp3 && lame --decode {$tmpname}.mp3 {$tmpname}.wav");
command = ["lame", "--silent", "--decode", input_filename, output_filename]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=subprocess_flags)
(stdout, stderr) = process.communicate()
if process.returncode != 0 or not os.path.exists(output_filename):
raise AudioProcessingException, stdout
return output_filename