简体   繁体   中英

Pyinstaller EXE will only run from CMD, clicking on the EXE doesn't work

I have made a simple python program for a friend of mine that makes use of tkinter and SMTPlib . I used pyinstaller to make an .exe for the program, but when I double click the .exe my CMD terminal will flash on the screen for a split second than disappear. When I drag that same .exe to my CMD terminal and press enter, the program runs with no issues, every feature of the program works.

I am attaching my .spec file that pyinstaller created, I have not modified it at all. I really feel like it should work, given that it 100% works if I call it from the CMD, only issues are when I double-click on the .exe. Extremely frustrating.

I have seen this same issue posted online several times, and there is no solution I have seen that has helped me. Any help would be greatly appreciated.

EDIT: Following the advice below I was able to get the program to run. I had to change the .spec file, specifically the datas field in order to get it to work. However I am now having a problem where the .txt files will load, but upon editing them the edits are not saved as they should be. The edits were all being saved BEFORE I fixed the original issue, when I was only able to run the program from the CMD. I am posting the entire script below:

EDIT II: I had not put the files into 'w' mode, and this is why I wasn't getting any output to the text files. All is working now!

My spec file:

block_cipher = None


a = Analysis(['test.py'],
             pathex=['C:\\Users\\wiley\\PycharmProjects\\EmailBot\\email_bot2'],
             binaries=[],
             datas=[('students1.txt', '.'),('students2.txt','.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='test',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='test')

my main.py file:

from tkinter import *
from tkinter import ttk
import re
import email_data
import smtplib
import os

__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))

student_view = None
email_string = ''


def display_email():
    def save_and_close():
        preview_window.destroy()

    preview_window = Toplevel()
    preview_window.title("Preview")
    preview_window.geometry('-680+300')
    preview_window.grab_set()
    preview_window.lift(root)

    preview_frame = ttk.Frame(preview_window, padding=10)
    preview = Text(preview_frame)
    close_button = Button(preview_frame, text='Close', command=save_and_close)

    preview_frame.grid()
    preview.grid(column=0, row=0, sticky='NSEW')
    close_button.grid(column=0, row=1, sticky='NSEW')

    preview.insert(END, email_string)


def format_email():
    global email_string
    email_string = email_data.email_string_raw.format(this_lab_name=t1.get(), zoom_date_time=t2.get(),
                                                      zoom_link=t3.get(),
                                                      zoom_ID=t4.get(),
                                                      zoom_passcode=t5.get(), this_lab_supplemental=t6.get(),
                                                      this_lab_consisting=t7.get(),
                                                      this_lab_due=t8.get(), file_name_tag=t9.get(),
                                                      last_lab_reminder=t10.get(),
                                                      last_lab_due=t11.get(),
                                                      last_lab_supplemental=t12.get(), last_file_name_tag=t13.get())
    view_email_button['state'] = 'normal'
    send_button['state'] = 'normal'


def send_email():
    global p, z, email_string, emails1, emails2

    def send_email_final():
        smtp_obj = smtplib.SMTP('smtp.office365.com', port=587)
        smtp_obj.starttls()
        email = email_input.get()
        password = email_pass_input.get()
        smtp_obj.login(email, password)

        from_address = email_input.get()

        msg = "Subject: CHML101: Weekly Instructional Email" + '\n\n' + email_string
        to_address_list = []
        if p.get() == 1:
            data = open(os.path.join(__location__, 'students1.txt'))
            emails = data.read()
            to_address_list = emails.split('\n')
            print(to_address_list.__str__())
        elif p.get() == 2:
            data = open(os.path.join(__location__, 'students2.txt'))
            emails = data.read()
            to_address_list = emails.split('\n')
            print(to_address_list.__str__())

        print(msg)
        smtp_obj.sendmail(from_address, to_address_list, msg)

    def confirm_normal():
        confirm_check['state'] = 'normal'

    def send_normal():
        if z.get() == 1:
            send_email_button['state'] = 'normal'
        else:
            send_email_button['state'] = 'disabled'

    send_email_window = Toplevel()
    send_email_window.title("Send Email")
    send_email_window.geometry('400x175-680+300')
    send_email_window.grab_set()
    send_email_window.lift(root)

    send_frame = ttk.Frame(send_email_window)
    email_label = Label(send_frame, text='Enter your email address:')
    pass_label = Label(send_frame, text='Enter your email password:')
    email_input = Entry(send_frame)
    email_pass_input = Entry(send_frame, show='*')
    class_label1 = Label(send_frame, text='Email class 1:')
    class_label2 = Label(send_frame, text='Email class 2:')
    class_radio1 = Radiobutton(send_frame, var=p, value=1, command=confirm_normal)
    class_radio2 = Radiobutton(send_frame, var=p, value=2, command=confirm_normal)
    confirm_label = Label(send_frame, text='Confirm selection:')
    confirm_check = Checkbutton(send_frame, state='disabled', variable=z, command=send_normal)
    send_email_button = Button(send_frame, text='Send Email', state='disabled', command=send_email_final)

    send_frame.grid(column=0, row=0, sticky='NSEW')
    email_label.grid(column=0, row=0, columnspan=2)
    pass_label.grid(column=2, row=0, columnspan=2)
    email_input.grid(column=0, row=1, columnspan=2)
    email_pass_input.grid(column=2, row=1, columnspan=2)
    class_label1.grid(column=0, row=2)
    class_label2.grid(column=2, row=2)
    class_radio1.grid(column=1, row=2)
    class_radio2.grid(column=3, row=2)
    confirm_label.grid(column=1, row=3)
    confirm_check.grid(column=2, row=3)
    send_email_button.grid(columnspan=2, column=1, row=4)


def class_list_view():
    global emails1, emails2, v, student_view

    def update_txt():
        items = student_view.get(0, 'end')
        if v.get() == 2:
            data1 = open(os.path.join(__location__, 'students2.txt'), mode='w')
            first = True
            for item in items:
                if first:
                    data1.write(item)
                    first = False
                else:
                    data1.write('\n' + item)
            data1.close()
        if v.get() == 1:
            data1 = open(os.path.join(__location__, 'students1.txt'), mode='w')
            first = True
            for item in items:
                if first:
                    data1.write(item)
                    first = False
                else:
                    data1.write('\n' + item)
            data1.close()

    def check_email():
        email = add_student_entry.get()
        if re.match(r'\w+@\w+.\w+', email) is not None:
            add_student()
            add_student_label['text'] = 'Add new student Email:'
            update_txt()
        else:
            add_student_label['text'] = 'EMAIL FORMAT INVALID'

    def delete_student():
        student_view.delete('active')
        update_txt()

    def add_student():
        if v.get() == 2:
            emails2_curr = emails2.get()
            emails2_curr = list(emails2_curr)
            emails2_curr.append(add_student_entry.get())
            emails2.set(emails2_curr)
            add_student_entry.delete(0, 'end')
        if v.get() == 1:
            emails1_curr = emails1.get()
            emails1_curr = list(emails1_curr)
            emails1_curr.append(add_student_entry.get())
            emails1.set(emails1_curr)
            add_student_entry.delete(0, 'end')

    def assign_class():
        if v.get() == 2:
            student_view['listvariable'] = emails2
        elif v.get() == 1:
            student_view['listvariable'] = emails1

    class_list = Toplevel()
    class_list.title("View/Edit Class Lists")
    class_list.geometry('400x200-680+300')
    class_list.grab_set()
    class_list.lift(root)

    student_frame = ttk.Frame(class_list)
    student_view = Listbox(student_frame, height=10, width=30)
    class1 = Radiobutton(student_frame, text='Class 1', var=v, value=1, command=assign_class)
    class2 = Radiobutton(student_frame, text='Class 2', var=v, value=2, command=assign_class)
    add_student_label = Label(student_frame, text='Add new student Email:')
    add_student_entry = Entry(student_frame, width=30)
    add_student_button = Button(student_frame, text='Add', command=check_email)
    delete_student_button = Button(student_frame, text='Delete', command=delete_student)

    add_student_entry.grid(column=2, row=1, sticky=N)
    add_student_label.grid(column=2, row=0, sticky=(N, E, W))
    add_student_button.grid(column=2, row=2)
    delete_student_button.grid(column=2, row=3)
    student_frame.grid(column=0, row=0, sticky=(N, S, E, W))
    student_view.grid(column=3, row=0, columnspan=3, rowspan=8, sticky=(N, W, S, E))
    class1.grid(column=3, row=8)
    class2.grid(column=4, row=8)


root = Tk()
root.title("Dr. Emailio Robotus")
root.geometry('600x700-670+120')
root.minsize(400, 500)

v = IntVar()
p = IntVar()
z = IntVar()

t1 = StringVar()
t2 = StringVar()
t3 = StringVar()
t4 = StringVar()
t5 = StringVar()
t6 = StringVar()
t7 = StringVar()
t8 = StringVar()
t9 = StringVar()
t10 = StringVar()
t11 = StringVar()
t12 = StringVar()
t13 = StringVar()

# data = open('students1.txt', encoding='utf-8')
data = open(os.path.join(__location__, 'students1.txt'))
emails = data.read()
emails1 = emails.split('\n')
emails1 = Variable(value=emails1)
data.close()

data = open(os.path.join(__location__, 'students2.txt'))
emails = data.read()
emails2 = emails.split('\n')
emails2 = Variable(value=emails2)
data.close()

mainframe = ttk.Frame(root, padding="5", borderwidth=5, relief='solid')

this_lab_name = ttk.Entry(mainframe, width=50, background='grey', textvariable=t1)
this_lab_name_label = Label(mainframe, text='This week\'s lab name:')

zoom_date_time = ttk.Entry(mainframe, width=50, background='grey', textvariable=t2)
zoom_date_time_label = Label(mainframe, text='This week\'s Zoom meeting (date/time):')

zoom_link = ttk.Entry(mainframe, width=50, background='grey', textvariable=t3)
zoom_link_label = Label(mainframe, text='This week\'s Zoom link:')

zoom_ID = ttk.Entry(mainframe, width=50, background='grey', textvariable=t4)
zoom_ID_label = Label(mainframe, text='This week\'s Zoom meeting ID:')

zoom_passcode = ttk.Entry(mainframe, width=50, background='grey', textvariable=t5)
zoom_passcode_label = Label(mainframe, text='This week\'s Zoom meeting passcode:')

this_lab_supplemental = ttk.Entry(mainframe, width=50, background='grey', textvariable=t6)
this_lab_supplemental_label = Label(mainframe, text='This week\'s lab\'s supplemental questions:')

this_lab_consisting = ttk.Entry(mainframe, width=50, background='grey', textvariable=t7)
this_lab_consisting_label = Label(mainframe, text='This week\'s lab should be consisting of:')

this_lab_due = ttk.Entry(mainframe, width=50, background='grey', textvariable=t8)
this_lab_due_label = Label(mainframe, text='This week\'s lab is due (date/time):')

file_name_tag = ttk.Entry(mainframe, width=50, background='grey', textvariable=t9)
file_name_tag_label = Label(mainframe, text='This week\'s lab naming format (Aspirin/Hess):')

last_lab_reminder = ttk.Entry(mainframe, width=50, background='grey', textvariable=t10)
last_lab_reminder_label = Label(mainframe, text='Last week\'s lab name:')

last_lab_due = ttk.Entry(mainframe, width=50, background='grey', textvariable=t11)
last_lab_due_label = Label(mainframe, text='Last week\'s lab is due (date/time):')

last_lab_supplemental = ttk.Entry(mainframe, width=50, background='grey', textvariable=t12)
last_lab_supplemental_label = Label(mainframe, text='Last week\'s lab\'s supplemental questions:')

last_file_name_tag = ttk.Entry(mainframe, width=50, background='grey', textvariable=t13)
last_file_name_tag_label = Label(mainframe, text='Last week\'s lab naming format (Aspirin/Hess):')

compile_button = Button(mainframe, text='Compile Email', command=format_email, width=25)
view_email_button = Button(mainframe, text='View Email', state='disabled', command=display_email, width=25)

classes_button = Button(mainframe, text='View/Modify Class List', command=class_list_view, width=18)

send_button = Button(mainframe, text='Send Email...', width=18, state='disabled', command=send_email)

mainframe.grid(column=0, row=0, sticky=(N, S, E, W))

this_lab_name.grid(column=1, row=0, sticky=E, padx=3, pady=3)
this_lab_name_label.grid(column=0, row=0, sticky=W, padx=3, pady=3)

zoom_date_time.grid(column=1, row=1, sticky=E, padx=3, pady=3)
zoom_date_time_label.grid(column=0, row=1, sticky=W, padx=3, pady=3)

zoom_link.grid(column=1, row=2, sticky=E, padx=3, pady=3)
zoom_link_label.grid(column=0, row=2, sticky=W, padx=3, pady=3)

zoom_ID.grid(column=1, row=3, sticky=E, padx=3, pady=3)
zoom_ID_label.grid(column=0, row=3, sticky=W, padx=3, pady=3)

zoom_passcode.grid(column=1, row=4, sticky=E, padx=3, pady=3)
zoom_passcode_label.grid(column=0, row=4, sticky=W, padx=3, pady=3)

this_lab_supplemental.grid(column=1, row=5, sticky=E, padx=3, pady=3)
this_lab_supplemental_label.grid(column=0, row=5, sticky=W, padx=3, pady=3)

this_lab_consisting.grid(column=1, row=6, sticky=E, padx=3, pady=3)
this_lab_consisting_label.grid(column=0, row=6, sticky=W, padx=3, pady=3)

this_lab_due.grid(column=1, row=7, sticky=E, padx=3, pady=3)
this_lab_due_label.grid(column=0, row=7, sticky=W, padx=3, pady=3)

file_name_tag.grid(column=1, row=8, sticky=E, padx=3, pady=3)
file_name_tag_label.grid(column=0, row=8, sticky=W, padx=3, pady=3)

last_lab_reminder.grid(column=1, row=9, sticky=E, padx=3, pady=3)
last_lab_reminder_label.grid(column=0, row=9, sticky=W, padx=3, pady=3)

last_lab_due.grid(column=1, row=10, sticky=E, padx=3, pady=3)
last_lab_due_label.grid(column=0, row=10, sticky=W, padx=3, pady=3)

last_lab_supplemental.grid(column=1, row=11, sticky=E, padx=3, pady=3)
last_lab_supplemental_label.grid(column=0, row=11, sticky=W, padx=3, pady=3)

last_file_name_tag.grid(column=1, row=12, sticky=E, padx=3, pady=3)
last_file_name_tag_label.grid(column=0, row=12, sticky=W, padx=3, pady=3)

compile_button.grid(column=0, row=13, columnspan=2, padx=3, pady=3)
view_email_button.grid(column=0, row=14, columnspan=2, padx=3, pady=3)
classes_button.grid(row=15, column=0, columnspan=2, padx=3, pady=3)
send_button.grid(row=16, column=0, columnspan=2, padx=3, pady=3)

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# mainframe.rowconfigure(0, weight=1)
# mainframe.columnconfigure(0, weight=1)
# mainframe.rowconfigure(0, weight=1)
# mainframe.columnconfigure(0, weight=1)


if __name__ == '__main__':
    root.mainloop()

Try the below spec file. I just changed the property console=True to console=False Note that now you need to run pyinstaller main.spec instead of pyinstaller main.py .

If you don't want to use this spec file, and just want to do it from the script add --noconsole or --windowed in command when you run pyinstaller main.py .

eg pyinstaller main.py --noconsole .

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['__main__.py'],
             pathex=['C:\\Users\\wiley\\PycharmProjects\\EmailBot\\email_bot'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='__main__',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=False)
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='__main__')

Following the advice given I was able to get the program to run. I had to change the .spec file, specifically the datas field in order to get it to work.

However I was then having a problem where the .txt files would load into the program, but upon editing them the edits were not saved as they should be. Solution: I had not put the files into 'w' mode, and this is why I wasn't getting any output to the text files. All is working now! Thank you to everyone for helping. I have updated the files above to reflect the final working version

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM