Why does my Program work as an exe file but not as an .app File on macOS?

Viewed 53

I coded a Selenium automation Tool with a GUI using Tkinter and Python. I use Pyinstaller to convert it to an .exe and .app File on my Mac running macOS Catalina 10.15.7. and python 3.8.5.

When converting the python program with pyinstaller (in terminal using :pyinstaller --noconsole --onefile --icon=exe-icon.icns --add-data username.txt:. --add-data password.txt:. -F bot.py)it creates both an .exe and a .app file. The .exe file runns perfectly as intended with the exception that I wasn't able to hide the console(--windowed,--noconsole,-w didn't work) and I wasn't able to set an icon. When running the .app file I have 2 main Problems(the GUI works as expcted):

1.My program saves userdata (password and username) on two different .txt files by writing and reading from them. When running my .app file however, it doesn't seem to be able to do so.Since I wasn't able to get a console runnign for the .app file I wasn't able to detect the Problem. Either the 2 extra wiles weren't added to the .app file or there is some other problem.

  def click():
     global userentry, passwordentry
     user = userentry.get()
     password = passwordentry.get()

     name = open(get_true_filename('username.txt'), 'w')
     name.write(user)
     code = open(get_true_filename('password.txt'), 'w')
     code.write(password)

  ...

  if data_submitted == False:
     global userentry, passwordentry
     # username label
     Label(frame2, text="Benutzer:").grid(row=2, column=0, sticky=W)
     # username entry
     global userentry
     userentry = Entry(frame2, width=20, bg="white")
     userentry.grid(row=3, column=0)

     # password label
     Label(frame2, text="Passwort:").grid(row=2, column=1, sticky=W)
     # password entry
     global passwordentry
     passwordentry = Entry(frame2, width=20, bg="white")
     passwordentry.grid(row=3, column=1)

     # submit button
     Button(frame2, text="BESTÄTIGEN", width=10, command=click).grid(row=6, column=0, sticky=W)

` The program checks if the textfiles already have been appendet to and if not sets data_submittet=False. On click() the data entered is appendet to the files. But when running as an .app file the form always pops up again.

2.The main Program runs a selenium skript,but somehow the program isn't able to execute it.

# coding=utf8
from selenium import webdriver
from time import sleep

from selenium.common.exceptions import NoSuchElementException
from webdriver_manager.firefox import GeckoDriverManager


class InstaBot:

   def login(self, username, pw):

        # setup headless firefox window

        self.options = webdriver.FirefoxOptions()
        #self.options.headless = True


       self.driver =  webdriver.Firefox(executable_path=GeckoDriverManager().install(),options=self.options)
       self.driver.set_window_size(1024, 868)
       # start instagram
       self.username = username
       self.driver.get("https://instagram.com")
       sleep(2)
       # cookies akzeptieren
       try:
           self.driver \
               .click()
           sleep(1)
       except NoSuchElementException:
           sleep(1)
       # username
       self.driver.find_element_by_xpath("/html/body/div[1]/section/main/article/div[2]  /div[1]/div/form/div/div[1]/div/label/input")\
        .send_keys(username)
       sleep(1)
       # password
       self.driver.find_element_by_xpath("/html/body/div[1]/section/main/article/div[2]/div[1]/div/form/div/div[2]/div/label/input")\
           .send_keys(pw)
       sleep(1)
       # login
       self.driver \
           .click()
       sleep(3)
       # login information speichern nein
       try:
          sleep(2)
          self.driver \
            .click()
          sleep(2)
       except NoSuchElementException:
           sleep(1)
       # benachrichtigungen: --> nicht jetzt
       try:
           sleep(4)
           self.driver \
               .click()
           sleep(2)
       except NoSuchElementException:
           sleep(1)
           print('fail')
           sleep(3)
           self.driver \
               .click()
           pass

The function is called by:

def get_password_username():
   passw = open(get_true_filename('password.txt'), 'r')
   password = passw.read()
   name = open(get_true_filename('username.txt'), 'r')
   username = name.read()
   return password, username

 ...
 Button(frame, text="Start", width=10, command=lambda :threading.Thread(target=self.start_function).start())
 ...
 def start_function(self):
    my_bot = InstaBot()
    if logdin == False:
       password, username = get_password_username()
       my_bot.login(username, password)
       logdin = True

I'm planning to run the browser headless once i works,but for now it doesn't even open firefox. The program just seems to be stuck right before the login method,but maybe that's because it trys to read the .txt files and it's stuck there. How can I make it work? Or is there a way to hide the console of the .exe and use that instead? Thanks in advance. (P.S. Tips on improving my question are welcome since this is my first one.)

0 Answers
Related