wxPopen.py
changeset 154 f3134b2c6d92
parent 151 43614ea83d2a
child 162 bf3eac08a96b
equal deleted inserted replaced
153:b352a2012691 154:f3134b2c6d92
    26 import time
    26 import time
    27 import wx
    27 import wx
    28 import subprocess, ctypes
    28 import subprocess, ctypes
    29 import threading
    29 import threading
    30 import os
    30 import os
       
    31 import signal
    31 
    32 
    32     
    33     
    33 class outputThread(threading.Thread):
    34 class outputThread(threading.Thread):
    34     """
    35     """
    35     Thread is used to print the output of a command to the stdout
    36     Thread is used to print the output of a command to the stdout
    62             wx.CallAfter(self.endcallback, self.Proc.pid, err)
    63             wx.CallAfter(self.endcallback, self.Proc.pid, err)
    63 
    64 
    64 class ProcessLogger:
    65 class ProcessLogger:
    65     def __init__(self, logger, Command, finish_callback=None, no_stdout=False, no_stderr=False, no_gui=True):
    66     def __init__(self, logger, Command, finish_callback=None, no_stdout=False, no_stderr=False, no_gui=True):
    66         self.logger = logger
    67         self.logger = logger
    67         self.Command = Command
    68         self.Command_str = Command
       
    69         self.Command = []
       
    70         for i,word in enumerate(Command.replace("'",'"').split('"')):
       
    71             if i % 2 == 0:
       
    72                 word = word.strip()
       
    73                 if len(word) > 0:
       
    74                     self.Command.extend(word.split())
       
    75             else:
       
    76                 self.Command.append(word)
       
    77         
    68         self.finish_callback = finish_callback
    78         self.finish_callback = finish_callback
    69         self.no_stdout = no_stdout
    79         self.no_stdout = no_stdout
    70         self.no_stderr = no_stderr
    80         self.no_stderr = no_stderr
    71         self.startupinfo = None
    81         self.startupinfo = None
    72         self.errlen = 0
    82         self.errlen = 0
    84         if no_gui == True and wx.Platform == '__WXMSW__':
    94         if no_gui == True and wx.Platform == '__WXMSW__':
    85             self.startupinfo = subprocess.STARTUPINFO()
    95             self.startupinfo = subprocess.STARTUPINFO()
    86             self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    96             self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    87             popenargs["startupinfo"] = self.startupinfo
    97             popenargs["startupinfo"] = self.startupinfo
    88         elif wx.Platform == '__WXGTK__':
    98         elif wx.Platform == '__WXGTK__':
    89             popenargs["shell"] = True
    99             popenargs["shell"] = False  #True
    90         
   100         
    91         self.Proc = subprocess.Popen( self.Command, **popenargs )
   101         self.Proc = subprocess.Popen( self.Command, **popenargs )
    92 
   102 
    93         self.outt = outputThread(
   103         self.outt = outputThread(
    94                       self.Proc,
   104                       self.Proc,
   119 
   129 
   120     def finish(self, pid,ecode):
   130     def finish(self, pid,ecode):
   121         self.finished = True
   131         self.finished = True
   122         self.exitcode = ecode
   132         self.exitcode = ecode
   123         if self.exitcode != 0:
   133         if self.exitcode != 0:
   124             self.logger.write(self.Command + "\n")
   134             self.logger.write(self.Command_str + "\n")
   125             self.logger.write_warning("exited with status %s (pid %s)\n"%(str(ecode),str(pid)))
   135             self.logger.write_warning("exited with status %s (pid %s)\n"%(str(ecode),str(pid)))
   126         if self.finish_callback is not None:
   136         if self.finish_callback is not None:
   127             self.finish_callback(self,ecode,pid)
   137             self.finish_callback(self,ecode,pid)
   128 
   138 
   129     def kill(self):
   139     def kill(self):
   133             PROCESS_TERMINATE = 1
   143             PROCESS_TERMINATE = 1
   134             handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.Proc.pid)
   144             handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.Proc.pid)
   135             ctypes.windll.kernel32.TerminateProcess(handle, -1)
   145             ctypes.windll.kernel32.TerminateProcess(handle, -1)
   136             ctypes.windll.kernel32.CloseHandle(handle)
   146             ctypes.windll.kernel32.CloseHandle(handle)
   137         else:
   147         else:
   138             os.kill(self.Proc.pid)
   148             try:
       
   149                 os.kill(self.Proc.pid, signal.SIGTERM)
       
   150             except:
       
   151                 pass
   139 
   152 
   140     def spin(self, timeout=None, out_limit=None, err_limit=None, keyword = None, kill_it = True):
   153     def spin(self, timeout=None, out_limit=None, err_limit=None, keyword = None, kill_it = True):
   141         count = 0
   154         count = 0
   142         while not self.finished:
   155         while not self.finished:
   143             if err_limit and self.errlen > err_limit:
   156             if err_limit and self.errlen > err_limit: