子流程有时发送返回为空

时间:2018-07-27 12:02:38

标签: windows python-3.x subprocess pyqt5 pyinstaller

我有以下用于运行我无法控制的第三方命令行工具的类。

我在Qthread Gui中运行了PyQt

我使用guiEXE变成Pyinstaller

当问题为EXE

时,问题更为普遍
class CLI_Interface:

    def process_f(self, command, bsize=4096):

        self.kill_process(CLI_TOOL)

        startupinfo = STARTUPINFO()
        startupinfo.dwFlags |= STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = SW_HIDE

        p = Popen(command, stdout=PIPE, stderr=PIPE,
                  startupinfo=startupinfo, bufsize=bsize, universal_newlines=True) 
        try:
             out, err = p.communicate(timeout=120)            
        except TimeoutExpired:
            p.kill()            
            out, err = p.communicate()
        return out.split(), err.split()


    def kill_process(self, proc):
        # Check process is running, Kill it if it is,
        #  return False if not.
        # uses its own popen for Stderr >> stdout
        #  If we use the self.process_f method, it will create an infinite loop

        startupinfo = STARTUPINFO()
        startupinfo.dwFlags |= STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = SW_HIDE
        try:
            kill_proc = Popen("TaskKill /IM {} /T /F".format(proc), stdout=PIPE, stderr=STDOUT,
                              startupinfo=startupinfo, universal_newlines=True).communicate()[0]
            if 'ERROR' not in kill_proc.split():
                return True  # Process Killed
            else:
                self.kill_process(proc)
        except Exception as e:
            return False


    def download_data(self, code):
        """ download data from the device based on a 5 digit code """

        command = '"{}" -l {},{} {}'.format(CLI_TOOL_PATH,
                                            code[0], code[2], code[1]) 
        try:
            p = self.process_f(command)
            proc, err = p[0], p[1]   
            try:
                if err[-2] == '-p':
                    return False
                return True
            except IndexError:
                if not proc:
                    return False # This means there is no data but the file is still saved!!
                pass
            return True            
        except Exception as e:
            return False

    def ....
    def ....
    def ....

线程:

class GetDataThread(QThread):

    taskFinished = pyqtSignal()
    notConnected = pyqtSignal()

    def __init__(self, f, parent=None):
        super(GetDataThread, self).__init__(parent)
        self.f = f

    def run(self):        

        is_dongle_connected()

        DD = cli.download_data(self.f)

        if not DD:
            self.notConnected.emit()
        else:
            self.taskFinished.emit()

我得到done!error-从命令行运行时,这是正常现象。

有时候我得到一个empty list的返回,并且在终止程序后将其放回递归循环中。

但是,它似乎无法正确重新启动,问题仍然存在-它陷入了无所事事的循环!。

与此同时,cli工具生成的csv文件是正常创建的,但我没有来自stdout / stderr的数据

看一下conhostcli工具的进程没问题。

GUI将继续失败(直到我拔下插头并插入加密狗和/或重新启动程序/计算机。

当我打开CLI并运行相同的命令时,它可以正常工作或引发错误(我在程序中捕获了问题)

我尝试设置缓冲区,因为生成的某些文件可以到达2.4mb

我尝试设置更高的超时时间以使其结束。

尽管似乎与文件大小没有关联,但它可能卡在任何大小。

流程如下:

Gui >> CLI >>加密狗>>传感器

在Windows 10上运行

如何使连接更牢固或调试可能仍在徘徊的进程并阻止它?

它阻止了吗?

是管道缓冲区溢出吗? -如果是,该如何确定正确的bufsize

与PyQt和Python Subprocess或Pyinstaller有关系吗?

使用QProcess代替Subprocess会更好吗?

谢谢!

0 个答案:

没有答案