Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PyInstaller Problem] Failed to execute script on calling subprocess #2087

Closed
3 tasks
thelou1s opened this issue Oct 17, 2019 · 8 comments
Closed
3 tasks

[PyInstaller Problem] Failed to execute script on calling subprocess #2087

thelou1s opened this issue Oct 17, 2019 · 8 comments

Comments

@thelou1s
Copy link

thelou1s commented Oct 17, 2019

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()
@PySimpleGUI
Copy link
Owner

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?

@PySimpleGUI PySimpleGUI changed the title [Bug] Failed to execute script on calling subprocess [PyInstaller Problem] Failed to execute script on calling subprocess Oct 17, 2019
@thelou1s
Copy link
Author

thelou1s commented Oct 18, 2019

“ 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?

@thelou1s
Copy link
Author

solved by change to this:

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

@PySimpleGUI
Copy link
Owner

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!

@ahmadasmandar
Copy link

solved by change to this:

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

thank you very much you saved my day.

@PySimpleGUI
Copy link
Owner

A new set of API calls is being added this year..... the "exec SDK". These will simplify these kinds of operations for users (and for PySimpleGUI itself since it's also launching subprocesses and threads). There's a single, non-published function at the moment that can launch subprocesses and it uses similar settings:

        sp = Popen([command, expanded_args], shell=True, stdout=PIPE, stderr=PIPE)

The overarching kinds of features it's being used for internally are for taking users to errors in their code when one is detected and for the demo programs that are self-editing or have features to edit other programs. The "Demo Browser" and "Project browser" are 2 recent examples.

image

Almost all of my programs have an "Edit me" capability, whether it's a button or a menu item:

image

This feature will be brought into PySimpleGUI itself as part of these new Exec APIs.

@praveenkumar-s
Copy link

solved by change to this:

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

Thank you !! this really saved me a lot of time

@PySimpleGUI
Copy link
Owner

This is the same call that you'll end up with by calling sg.execute_command_subprocess without any arguments.

I'm using this API extensively now with the Demo Browser, the PySimpleHotkey that was recently released and a program being used to test the releases of PySimpleGUI.

If you're already comfortable with the subprocess API calls, then you're in a good shape. I'm providing them for convenience as well as making the demos so that all levels of programmers can use them... at least that's the theory. :-)

The "Edit Me" feature has been added to pretty much every new program I write that I use myself. It's made debugging so much easier as I never have to remember where I've saved the file.

Glad to see PySimpleGUI being used with subprocesses either way. Post what you're making if you get a chance. I'm definitely interested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants