0

I am creating an app while converts python files to exe files. I am trying to use os.system() method, but it displays the console window, which I don't want.

What I want to do:

  1. Hide the console window
  2. Add a progress bar (if possible)
  3. Prevent the app from going 'Not responding' (hanging).
  4. Send a notification to the user after the exe is created (I can use win10toasts module for this)

How can I do that?

Here's the current code:

from tkinter import Tk, messagebox as mb
from tkinter.ttk import Button, Label
import os

root = Tk()
root.title("Creating exe")
root.geometry("500x500")

def create_exe_onefile(item):
    try:
        if os.path.exists(pyinstaller_path) or os.path.exists(pyinstaller_path2):
            pass
        else:
            os.system("pip install pyinstaller")
        if os.path.exists("Apps Created\\Executables"):
                pass
        else:
            os.mkdir("Apps Created\\Executables")
        os.system(f'pyinstaller --onefile -w "{item}"')
        path = fd.askdirectory(title="Where to save the exe?")
        if path:
            fi = item.replace('.pyw', '')
            try:
                os.mkdir(f"Apps Created\\Executables\\{fi}")
            except Exception:
                pass
            for j in os.listdir(f"build\\{fi}"):
                os.remove(j)
            os.rmdir(f"build\\{fi}")
            os.rmdir("build")
            shutil.move(f"dist\\{item}", f"Apps Created\\Executables\\{fi}")
            for i in os.listdir(f"dist\\{fi}"):
                os.remove(i)
            os.rmdir(f"dist\\{fi}")
            os.rmdir("dist")
            for i in os.listdir("__pycache__"):
                os.remove(i)
            os.rmdir("__pycache__")
            os.remove(f"{fi}.spec")
            shutil.copytree(f"Apps Created\\Executables\\{fi}\\{item}", path)
            mb.showinfo("Done", f"File copied.\nYou can find your exe file in {path}.\nA copy of your exe has been saved in {os.getcwd()}\\Apps Created\\Executables")
    except Exception as err:
        mb.showerror("Error", f"Error while creating the exe!\n{err}")
        exit()


status = Label(root, text="Please wait while the exe is being created...", font="Calibri 20")
status.pack(pady=50)

stb = Button(root, text="Start", command=lambda: convert_exe_onefile("main.pyw"))
stb.pack(pady=30)

# If possible, I want to add a progressbar here to show the status of exe creation.

root.mainloop()
IJ_123
  • 457
  • 6
  • 13
  • try using `subprocess.Popen` from [`subprocess`](https://docs.python.org/3/library/subprocess.html) module (built-in) – Matiiss Aug 23 '21 at 15:42
  • Do you mean replace ```os.system()``` with ```subprocess.Popen()```? But I think that will still open a new terminal/cmd window, which I don't want. I want a silent conversion without showing the cmd. – IJ_123 Aug 24 '21 at 05:10
  • you think or you know? go and test it, then tell me that it doesn't work – Matiiss Aug 24 '21 at 05:13
  • Yes, I have tried it. It still shows the console. Is this the correct usage? ```subprocess.Popen(f'pyinstaller --onefile -w "{item}"', "cmd.exe")``` – IJ_123 Aug 24 '21 at 05:19
  • Also, I tried to invert it by doing ```subprocess.Popen("cmd.exe", f'pyinstaller --onefile -w "{item}"')``` but in vain. It still shows the window. – IJ_123 Aug 24 '21 at 05:21
  • what is `cmd.exe` doing there? I am pretty sure that that argument doesn't have to be specified, and the second way seems to be incorrect – Matiiss Aug 24 '21 at 05:22
  • also another important thing is ... did you convert this script to an `.exe`? because you can specify the nowindowed mode when doing that, and if you don't, your window will always open with console – Matiiss Aug 24 '21 at 05:25
  • another thing you may want to do is this: `subprocess.Popen(f'pyinstaller --onefile -w "{item}"', stdout=subprocess.PIPE, stderr=subprocess.PIPE)`, usually pipes are meant for communicating with the proces but if you don't specify anything, it just shouldn't output anything – Matiiss Aug 24 '21 at 05:32
  • I have tried everything you gave. Even the ```subprocess.Popen(f'pyinstaller --onefile -w "{item}"', stdout=subprocess.PIPE, stderr=subprocess.PIPE)``` method, but it still shows the console. Also, when I added the pipe method, it does nothing. – IJ_123 Aug 24 '21 at 07:00
  • does it show the console before you run any commands in it, is this an `.exe` file? and yes it does nothing because it simply redirects the stdout and stderr to a pipe and that pipe isn't being read – Matiiss Aug 24 '21 at 07:03
  • It doesn't show the console before. It shows it only when some command is run like ```pyinstaller```. Yes, it's an exe. By using pipes, it just skips that part and proceeds to the next command. – IJ_123 Aug 24 '21 at 07:18
  • Does this answer your question? [How do I hide the console when I use os.system() or subprocess.call()?](https://stackoverflow.com/questions/7006238/how-do-i-hide-the-console-when-i-use-os-system-or-subprocess-call) Also you could have simply [asked this your favorite search engine](https://www.google.com/search?q=how+to+hide+console+when+using+os.system), also it doesn't skip the command, you simply don't see the output because it is redirected to a pipe – Matiiss Aug 24 '21 at 07:22

0 Answers0