处理Windows下的子进程崩溃

23 投票
2 回答
10250 浏览
提问于 2025-04-16 12:14

我在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

撰写回答