无法运行python exe

问题描述 投票:2回答:2

所以我在让python 3.5脚本作为exe运行时遇到问题。这是我正在使用的代码:

import base64
import imaplib
import json
import smtplib
import urllib.parse
import urllib.request
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import lxml.html

GOOGLE_ACCOUNTS_BASE_URL = 'https://accounts.google.com'
REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'

GOOGLE_CLIENT_ID = '<FILL ME IN>'
GOOGLE_CLIENT_SECRET = '<FILL ME IN>'
GOOGLE_REFRESH_TOKEN = None


def command_to_url(command):
    return '%s/%s' % (GOOGLE_ACCOUNTS_BASE_URL, command)


def url_escape(text):
    return urllib.parse.quote(text, safe='~-._')


def url_unescape(text):
    return urllib.parse.unquote(text)


def url_format_params(params):
    param_fragments = []
    for param in sorted(params.items(), key=lambda x: x[0]):
        param_fragments.append('%s=%s' % (param[0], url_escape(param[1])))
    return '&'.join(param_fragments)


def generate_permission_url(client_id, scope='https://mail.google.com/'):
    params = {}
    params['client_id'] = client_id
    params['redirect_uri'] = REDIRECT_URI
    params['scope'] = scope
    params['response_type'] = 'code'
    return '%s?%s' % (command_to_url('o/oauth2/auth'), url_format_params(params))


def call_authorize_tokens(client_id, client_secret, authorization_code):
    params = {}
    params['client_id'] = client_id
    params['client_secret'] = client_secret
    params['code'] = authorization_code
    params['redirect_uri'] = REDIRECT_URI
    params['grant_type'] = 'authorization_code'
    request_url = command_to_url('o/oauth2/token')
    response = urllib.request.urlopen(request_url, urllib.parse.urlencode(params).encode('UTF-8')).read().decode('UTF-8')
    return json.loads(response)


def call_refresh_token(client_id, client_secret, refresh_token):
    params = {}
    params['client_id'] = client_id
    params['client_secret'] = client_secret
    params['refresh_token'] = refresh_token
    params['grant_type'] = 'refresh_token'
    request_url = command_to_url('o/oauth2/token')
    response = urllib.request.urlopen(request_url, urllib.parse.urlencode(params).encode('UTF-8')).read().decode('UTF-8')
    return json.loads(response)


def generate_oauth2_string(username, access_token, as_base64=False):
    auth_string = 'user=%s\1auth=Bearer %s\1\1' % (username, access_token)
    if as_base64:
        auth_string = base64.b64encode(auth_string.encode('ascii')).decode('ascii')
    return auth_string


def test_imap(user, auth_string):
    imap_conn = imaplib.IMAP4_SSL('imap.gmail.com')
    imap_conn.debug = 4
    imap_conn.authenticate('XOAUTH2', lambda x: auth_string)
    imap_conn.select('INBOX')


def test_smpt(user, base64_auth_string):
    smtp_conn = smtplib.SMTP('smtp.gmail.com', 587)
    smtp_conn.set_debuglevel(True)
    smtp_conn.ehlo('test')
    smtp_conn.starttls()
    smtp_conn.docmd('AUTH', 'XOAUTH2 ' + base64_auth_string)


def get_authorization(google_client_id, google_client_secret):
    scope = "https://mail.google.com/"
    print('Navigate to the following URL to auth:', generate_permission_url(google_client_id, scope))
    authorization_code = input('Enter verification code: ')
    response = call_authorize_tokens(google_client_id, google_client_secret, authorization_code)
    return response['refresh_token'], response['access_token'], response['expires_in']


def refresh_authorization(google_client_id, google_client_secret, refresh_token):
    response = call_refresh_token(google_client_id, google_client_secret, refresh_token)
    return response['access_token'], response['expires_in']


def send_mail(fromaddr, toaddr, subject, message):
    access_token, expires_in = refresh_authorization(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REFRESH_TOKEN)
    auth_string = generate_oauth2_string(fromaddr, access_token, as_base64=True)

    msg = MIMEMultipart('related')
    msg['Subject'] = subject
    msg['From'] = fromaddr
    msg['To'] = toaddr
    msg.preamble = 'This is a multi-part message in MIME format.'
    msg_alternative = MIMEMultipart('alternative')
    msg.attach(msg_alternative)
    part_text = MIMEText(lxml.html.fromstring(message).text_content().encode('utf-8'), 'plain', _charset='utf-8')
    part_html = MIMEText(message.encode('utf-8'), 'html', _charset='utf-8')
    msg_alternative.attach(part_text)
    msg_alternative.attach(part_html)
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo(GOOGLE_CLIENT_ID)
    server.starttls()
    server.docmd('AUTH', 'XOAUTH2 ' + auth_string)
    server.sendmail(fromaddr, toaddr, msg.as_string())
    server.quit()

def main():
    if GOOGLE_REFRESH_TOKEN is None:
        print('No refresh token found, obtaining one')
        refresh_token, access_token, expires_in = get_authorization(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
        print('Set the following as your GOOGLE_REFRESH_TOKEN:', refresh_token)
        exit()

    send_mail('[email protected]', '[email protected]',
                'A mail from you from Python',
                '<b>A mail from you from Python</b><br><br>' +
                'So happy to hear from you!')
    input("Success!")

print(__name__)
input("Wait!!")
if __name__ == '__main__':
    main()

当我在pyCharm中运行代码时,效果很好,当我使用pyinstaller时,它会创建exe。当我运行EXE时,它将打开没有文本的新cmd prmpt,然后将其关闭。任何不显示名称或“ Wait !!”的想法屏幕上?我将文件命名为main,它在PyCharm中非常有用。我不熟悉在IDE中工作并且无法作为exe执行的故障排除代码。是否有基本的故障排除指南?

python exe
2个回答
1
投票

大多数问题是由导入的模块引起的错误。

我有两种想法

  1. 发生错误时,使用异常处理并使用traceback.format_exc()显示内容。
  2. 错误通常与sys.stderr相关联,因此您可以将stderr输出的指定格式重定向到指定文件等。

示例:

import sys
from pathlib import Path
from os import startfile
import traceback


DEBUG = True


class CaptureStderr:
    __slots__ = ('debug_flag',
                 'original',
                 'log',)

    def __init__(self, debug_flag=False, log=None):
        self.debug_flag = debug_flag
        self.original = sys.stderr  # Keep track of original
        self.log = log

    def new_log_file(self, log_path: Path = Path('temp.log').resolve()):
        self.log = open(str(log_path), 'w')
        return self.log

    def start(self):
        """ Start filtering and redirecting stderr """
        sys.stderr = self

    def stop(self):
        """ Stop filtering and redirecting stderr """
        sys.stderr = self.original

    def write(self, message: str):
        """ When sys.stderr.write is called, it will re directed here"""
        if not self.debug_flag:
            self.original.write(message)
            self.original.flush()
            return
        if self.log:
            self.log.write(message)


def main():
    ...


if __name__ == '__main__':
    try:  # method 1
        from .notexistmodule import notexistclass
        # Put modules that you are not sure whether it is 100% import successful on here.
        main()
    except:
        print(traceback.format_exc())

    # method 2: redirect sys.stderr
    cs = CaptureStderr(DEBUG)
    cs.new_log_file(Path('error.log'))
    cs.start()
    from .notexistmodule2 import notexistclass2
    main()
    cs.stop()
    startfile(cs.log.name)


0
投票

您可能在exe中有错误,很可能是导入错误。

像这样运行您的exe来查看错误:使用以下命令创建一个.bat文件来运行exe]。

start C:\Path\To\.exe
pause

这将阻止命令提示符退出,直到您按键盘上的某个键,才能读取输出。

© www.soinside.com 2019 - 2024. All rights reserved.