Pysimplegui: [PyInstaller Problem] Failed to execute script on calling subprocess

Created on 17 Oct 2019  ·  4Comments  ·  Source: PySimpleGUI/PySimpleGUI

Type of Issues

Bug

Operating System

Windows 7

Python version

3.5

PySimpleGUI Port and Version

4.4.1

Your Experience Levels In Months or Years

Python programming experience
1

Programming experience overall
7

Have used another Python GUI Framework (tkiner, Qt, etc) previously (yes/no is fine)?
yes

You have completed these steps:

  • [ yes] Read instructions on how to file an Issue
  • [ yes] Searched through main docs http://www.PySimpleGUI.org for your problem
  • [ ] Searched through the readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
  • [ ] Looked for Demo Programs that are similar to your goal http://www.PySimpleGUI.com
  • [ ] Note that there are also Demo Programs under each port on GitHub
  • [ yes] Run your program outside of your debugger (from a command line)
  • [ yes] Searched through Issues (open and closed) to see if already reported

Code or partial code causing the problem

I'm new to PySimpleGUI. When I use module subprocess and packaged py into exe, it always crash like screenshot below. But when I run my py file direct in cmd, it just fine. So anyone please tell me how to fix it? thx.

Exe file crash on Windows7 when click ok:
enter image description here

SimpleDemoTestSubprocess.py:

import PySimpleGUI as sg
import subprocess


def runCommand(cmd, timeout=None):
    """ run shell command
    @param cmd: command to execute
    @param timeout: timeout for command execution
    @return: (return code from command, command output)
    """

    prt('runCommand, cmd = ' + str(cmd))

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''

    prt('runCommand, communicate')
    out, err = p.communicate()
    prt('runCommand, wait')
    p.wait(timeout)

    prt(out)
    prt(err)

    return (out, err)


def prt(self, *args, sep=' ', end='\n', file=None):
    print()
    print(self, *args, sep=' ', end='\r\n', file=None)


# All the stuff inside your window.
layout = [
    [sg.Text('Some text on Row 1')]
    , [sg.Text('Enter something on Row 2'), sg.InputText()]
    , [sg.Button('Ok'), sg.Button('Cancel')]
    # , [sg.PopupScrolled('Hello From PySimpleGUI!', 'This is the shortest GUI program ever!')]
]

# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
    event, values = window.read()
    if event in (None, 'Cancel'):  # if user closes window or clicks cancel
        break
    if event in (None, 'Ok'):  # if user closes window or clicks cancel
        runCommand("ls")
    print('You entered ', values[0])

window.close()

package py into exe:

# https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_EXE_Maker.py

import PySimpleGUI as sg
import subprocess
from shutil import copyfile
import shutil
import os

def prt(self, *args, sep=' ', end='\n', file=None):
    print()
    print(self, *args, sep=' ', end='\r\n', file=None)

def Launcher():
    sg.ChangeLookAndFeel('LightGreen')

    layout = [[sg.T('PyInstaller EXE Creator', font='Any 15')],
              [sg.T('Source Python File'), sg.In(key='_sourcefile_', size=(45, 1)),
               sg.FileBrowse(file_types=(("Python Files", "*.py"),))],
              [sg.T('Icon File'), sg.In(key='_iconfile_', size=(45, 1)),
               sg.FileBrowse(file_types=(("Icon Files", "*.ico"),))],
              [sg.Frame('Output', font='Any 15', layout=[[sg.Output(size=(65, 15), font='Courier 10')]])],
              [sg.ReadFormButton('Make EXE', bind_return_key=True),
               sg.SimpleButton('Quit', button_color=('white', 'firebrick3')), ]]

    window = sg.Window('PySimpleGUI EXE Maker',
                       auto_size_text=False,
                       auto_size_buttons=False,
                       default_element_size=(20, 1,),
                       text_justification='right')

    window.Layout(layout)

    # ---===--- Loop taking in user input --- #
    while True:
        (button, values) = window.Read()
        if button in ('Quit', None):
            break  # exit button clicked

        source_file = values['_sourcefile_']
        icon_file = values['_iconfile_']

        icon_option = '-i "{}"'.format(icon_file) if icon_file else ''
        source_path, source_filename = os.path.split(source_file)
        workpath_option = '--workpath "{}"'.format(source_path)
        dispath_option = '--distpath "{}"'.format(source_path)
        specpath_option = '--specpath "{}"'.format(source_path)
        folder_to_remove = os.path.join(source_path, source_filename[:-3])
        file_to_remove = os.path.join(source_path, source_filename[:-3] + '.spec')
        command_line = 'pyinstaller -wF "{}" {} {} {} {}'.format(source_file, icon_option, workpath_option,
                                                                 dispath_option, specpath_option)

        if button == 'Make EXE':
            try:
                prt('source_file: ' + str(source_file))
                prt('Making EXE... this will take a while.. the program has NOT locked up...')
                window.Refresh()

                prt('window.Refresh')
                window.Refresh()
                prt('Running command: {}'.format(command_line))
                runCommand(command_line)
                shutil.rmtree(folder_to_remove)
                os.remove(file_to_remove)
                prt('**** DONE ****')
            except Exception as e:
                # sg.PopupError('Something went wrong')
                prt("Launcher, Exception = " + e)


def runCommand(cmd, timeout=None):
    """ run shell command
    @param cmd: command to execute
    @param timeout: timeout for command execution
    @return: (return code from command, command output)
    """

    prt('runCommand, cmd = ' + str(cmd))

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''

    prt('runCommand, communicate')
    out, err = p.communicate()
    prt('runCommand, wait')
    p.wait(timeout)

    prt(out)
    prt(err)

    return (out, err)

if __name__ == '__main__':
    Launcher()

Most helpful comment

solved by change to this:

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

All 4 comments

This is a problem with PyInstaller. I assume it all runs fine if you don't turn it into an EXE file. In the past I've not been able to turn the launcher demo programs you'll find here on the GitHub into EXE files due to PyInstaller problems.

I suggest checking stackoverflow or elsewhere on the more generic problem of Subprocess calls and PyInstaller.

If you strip out all of the PySimpleGUI code and just call the subprocess call from your EXE file, does that have problems? Can you try hard coding that and running a test?

“ I assume it all runs fine if you don't turn it into an EXE file”
yes, it is.

“If you strip out all of the PySimpleGUI code and just call the subprocess call from your EXE file, does that have problems?”
OK, I striped out all PySimpleGUI codes, and it still crash. so it has nothing to do with PySimpleGUI : )

So did PySimpleGUI support other EXE packager, rather than pyinstaller?

solved by change to this:

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

THANK YOU!!!!!!!!!

I've been trying to solve this problem for some time now. I really appreciate you not only digging and finding a solution, but also coming back and posting it. Very appreciated!

Was this page helpful?
0 / 5 - 0 ratings