pyinstaller: popen doesn't run after producing exe - python

I compiled my python application using pyinstaller and the exe works fine, but when I run it on a different machine without python any part of the code which contains subprocess.Popen()doesn't run.
I read too many questions but I couldn't wrap my head around this.
My popen line:
try:
process = subprocess.Popen(['python', os.path.abspath('about.py')],stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,
shell=True)
except Exception as e:
print(e)
Note that the executable runs on the host machine, but on another machines it runs but fails when launching the popen.
===UPDATE====
The console shows nothing and doesn't print an exception, so I guess this is a problem with python not being found. How can I fix this?
===UPDATE2====
Following the suggestion of viilpe I used "exec(open..." but it required me to import the about.py module first; importing the module runs it on top of the main module.
Putting exec(open...) inside the try\except runs the main module and the about module alongside each other; ruining the application's GUI.
I'm using "kivy" as my GUI library.

Looks like you want to execute about.py but there is no python.exe in pyinstaller bundle.
As advised here you can do it this way:
exec(open('about.py').read())

The whole point of PyInstaller is to make the destination computer be able to run your script without having a standalone python installation. You can't run a subprocess on a tool which isn't (necessarily) installed.
There are various ways to run Python as a subprocess of itself natively; start by exploring the multiprocessing library.
If the requirement to run Python twice is not a hard one, the absolutely simplest solution is to import about and run the code as part of your script. This probably requires some refactoring of the code in about.py.

Related

Is it possible to make a PyQt5 app that calls a python script via a subprocess fully self-contained?

Apologies if I am missing something obvious here. I have a PyQt5 app that I've frozen using the awesome fbs package. Within the app, a Python script is called via a PyQt subprocess, i.e. like this:
command = "python LaunchPPTKwin.py"
self.child = QProcess()
self.child.start("cmd.exe /C python LaunchPPTKwin.py")
self.child.waitForFinished(-1)
This works fine when the app is run on the machine on which the app was built. When I bring it to another machine, however, the app runs but the LaunchPPTKwin.py script is never executed. I assume this is because the other machine does not have python installed and/or does not have the LaunchPPTKwin.py script locally. My goal is to create an app so that this will work without the user needing to separately download python or the script, i.e. to make the app totally self contained. Is this possible using fbs?
P.S. Both machines are using Windows 10.
Either python is not installed or python is not in the search path and you had to locate it.
If python were installed, but not in the search path following code should work.
self.child.start("cmd.exe /C start LaunchPPTKwin.py")
If python is not installed at all you could cheat with more effort.
you had to make sure, that your frozen application can handle a command line parameter that allows it to start another script.
It would take the python file.
add the base directory of that file to sys.path strip of the .py suffix of the basename and import it and call it's main function. THis works however only if the script had following lines at its end
def main():
the_code_you_want_to_start
...
if __name__ == "__main__":
main()
It would further only work if all modules, that this file imports are already used by your frozen app.
So you see it's a little complicated, but I did something similiar with a py2exe application and with a pyinstaller application
Figured it out: I just compiled the Python script being called into an executable using Pyinstaller, and then called that executable. So my subprocess call above turned into:
command = "cmd.exe /C LaunchPPTKwin.exe"
self.child = QProcess()
self.child.start(command)
self.child.waitForFinished(-1)

Running an executable from Python "This application has requested the Runtime to terminate it in an unusual way."

I'm getting an interesting problem and I can't determine whether it's a problem with my code or the executable that I'm running. Basically I have a Python program that needs to call an external executable to process some data. If I call the executable via PowerShell or cmd, it works fine. However, if I attempt to run the executable via os.system() or subprocess.run(), I get the following error:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
From my understanding of googling the issue, it would appear that this is some sort of C++-related issue, which is the language of the .exe that I'm running. I reinstalled the latest Visual C++ Redist and that did not seem to affect the problem. I've also tried to create a .bat and .ps1 script that runs the .exe. These both run fine via PowerShell and CMD, but raise the same error when run via os.system() and subprocess.run(). The error message is rather nondescript so I'm wondering if anyone knows anything about it and why os.system() etc. might be throwing it.
The relevant code is simply
os.system("GaussBin.exe gaussInput.txt gaussOutput.txt")
When the string is pasted into cmd, it runs perfectly. Additionally, if the parameters of the system() call are incorrect, the exe properly displays the usage function. It's only when I add the output.txt and the program is supposed to run fully that things start to break.
I've had some confusion about what directory os.system runs in. Should I be using .\ when calling the exe?
The .exe file is provided, not built by me.

Embedded Python(C++) Import Locks up?

So we are using a python interpreter embedded in our C++ application (using Py_initialize,etc) to run various test scripts.
I am attempting to use the Pythonnet package.
Running a normal python interpreter i can run import clr and have no issues and can use pythonnet as expected.
If i attempt to run import clr in a script that runs in our embedded interpreter it locks up on that line. It never throws any errors or does anything, just sits there forever and i have no idea how to figure out what its doing.
I've attempted to use WinPdb but it also just locks up when i try to enter that statement.

python or pythonw in creating a cross-platform standalone GUI app

I am developing a simple standalone, graphical application in python. My development has been done on linux but I would like to distribute the application cross-platform.
I have a launcher script which checks a bunch of environment variables and then sets various configuration options, and then calls the application with what amounts to python main.py (specifically os.system('python main.py %s'% (arg1, arg2...)) )
On OS X (without X11), the launcher script crashed with an error like Could not run application, need access to screen. A very quick google search later, the script was working locally by replacing python main.py with pythonw main.py.
My question is, what is the best way to write the launcher script so that it can do the right thing across platforms and not crash? Note that this question is not asking how to determine what platform I am on. The solution "check to see if I am on OS X, and if so invoke pythonw instead" is what I have done for now, but it seems like a somewhat hacky fix because it depends on understanding the details of the windowing system (which could easily break sometime in the future) and I wonder if there is a cleaner way.
This question does not yet have a satisfactory answer.
If you save the file as main.pyw, it should run the script without opening up a new cmd/terminal.
Then you can run it as python main.pyw
Firstly, you should always use .pyw for GUIs.
Secondly, you could convert it to .exe if you want people without python to be able to use your program. The process is simple. The hardest part is downloading one of these:
for python 2.x: p2exe
for python 3.x: cx_Freeze
You can simply google instructions on how to use them if you decide to go down that path.
Also, if you're using messageboxes in your GUI, it won't work. You will have to create windows/toplevels instead.

subprocess running python getting import error

I'm trying to run a python script from a python program by kicking it off from subprocess (The reason is that the main program has to have exited when the script runs, with a combination of wx.CallAfter and Close). However when the script runs I get an error on line 1 with ImportError: No module named os which makes me think it's something to do with the PythonPath, but I can run the script just fine from a terminal.
Why can't the script see any core modules when run this way?
Edit:
The line in question is:
wx.CallAfter(subprocess.Popen,'python %s "%s" %s %s'%(os.path.join(BASE_DIR,"updatecopy.py"),BASE_DIR,pos[0],pos[1]),shell=True)
BASE_DIR is just the directory that the script lives in.
subprocess is there because os.exec* has been deprecated so I wouldn't suggest using that in place of Popen as someone suggested.
I've seen this issue crop up when running from a frozen process. If that is the case then you're most likely inheriting a weird environment for the new python process.
Most frozen scripts will be trying to run from a zip file, in which case it's no wonder that Python can't find anything, it's all trapped in a zip file :)
If this is the situation then try running using the python executable that you are using to run the frozen script. It should be able to deal with the special environment.
Maybe you could use os.execv instead of Popen.
From os/python docs:
These functions all execute a new program, replacing the current process; they do not return. On Unix, the new executable is loaded into the current process, and will have the same process id as the caller. Errors will be reported as OSError exceptions.
(emphasis mine)

Categories

Resources