[python学习笔记] py2exe 打包

遇坑

之前经过折腾,pyinstaller打包文件可以在别的windows7上运行。但是,mfk, 客户说是xp系统。崩溃

使用pyinstaller各种折腾,打包出来的依然是不是有效的win32程序,各种报错。

后来尝试使用 py2exe 打包

使用

  • 安装 不废话,下载exe版,傻瓜式安装
  • 使用
    • 编写类似一个 setup.py 文件,写各种配置(下边有)
    • 调用命令
    python setup.py py2exe
    • 或者在setup.py下添加如下语句,点击文件自动运行
    sys.argv.append('py2exe')
    • 官方示例: http://www.py2exe.org/index.cgi/Tutorial
    • 具体参数含义见:http://www.py2exe.org/index.cgi/ListOfOptions

问题

  • 不是有效的win32程序

    换32位的python,其他模块都重装,包括pyqt5

  • py2exe UnicodeDecodeError: 'gbk' codec can't decode

    py2exe 的runtime.py 里 打开文件制定为utf-8
    with open(target.script, "U",encoding="UTF-8") as script_file:
  • 编译PyQt5 异常

    把一句 Exception, e 该为 Exception as e 就好了
  • could not find or load the Qt platform plugin "windows"

    把 C:\Python34\Lib\site-packages\PyQt5\plugins 下的 platforms 拷贝到 打包目录下的platforms搞定

  • 找不到 msvc**100.dll 问题

    把system32 目录下的 msvc**.dll 的三个dll文件拷贝到打包目录下

分享一下完成的打包脚本

from distutils.core import setup
import py2exe
import sys
import os
import glob
import shutil
import msvcrt



#this allows to run it with a simple double click.
sys.argv.append('py2exe')
PYTHON_HOME = os.getenv('PYTHON_HOME')
TARGET_DIR = '../build2'

# 删除原来生成的路径
if os.path.exists(TARGET_DIR):
  print("是否删除文件夹(y/n)\t" + os.path.abspath(TARGET_DIR))
  d = msvcrt.getch()
  if d == b'y':
    shutil.rmtree(TARGET_DIR)
    print(os.path.abspath(TARGET_DIR)+'  被删除')



def find_data_files(dlist,source,target,patterns):
    # 是否有特殊符号
    if glob.has_magic(source) or glob.has_magic(target):
        raise ValueError("Magic not allowed in src, target")
    ret = dlist
    for pattern in patterns:
        # 给pattern 上添加目录
        pattern = os.path.join(source,pattern)
        # 通过pattern寻找满足条件的文件
        for filename in glob.glob(pattern):
            # 判断文件是否存在
            if os.path.isfile(filename):
                # 获取相对source 的相对路径
                relP = os.path.relpath(filename,source)
                # 设置为目标路径
                targetpath = os.path.join(target,relP)
                # 获取目标文件的文件夹
                path = os.path.dirname(targetpath)
                ret.setdefault(path,[]).append(filename) 
print('-------------------')
print('资源拷贝')
data_files = {}
# 拷贝xp需要的msvc**100.dll
find_data_files(data_files,'C:/Windows/System32/','',['msvc*100.dll'])
# 拷贝pyqt5里依赖的dll
find_data_files(data_files, PYTHON_HOME+'/Lib/site-packages/PyQt5/plugins/platforms','platforms',['*.dll'])
# 把当前目录下ui文件夹内容拷贝到目标文件夹的ui文件夹下
find_data_files(data_files,'ui','ui',['*.*'])
# 拷贝配置文件
find_data_files(data_files,'config/','config/',['*.*'])
# 转成键值对集合
data_files = data_files.items()
print(data_files)
print('--------------------------')

OPTIONS = {
  'py2exe': {
    "includes": ["sip"],# 导入依赖 sip
    # "dll_excludes": ["MSVCP90.dll","MSVCR100.dll"],
    # 是否压缩 1 压缩。 0 不压缩
    "compressed": 1,
    # 优化级别。 0 不优化 pyc 1 优化 pyd 2 pyo
    "optimize": 2,
    # 依赖的包
    "packages": ["xml.etree", "xml"],
    # 是否把dll打包到压缩包里
    # 1 所有的都打包  2 除了python解释器,其他的都打包 3 所有的不打包
    "bundle_files": 1,
    # 生成的文件夹
    'dist_dir':TARGET_DIR
  },

}
setup(
      name = '登录器',
      version = '1.0',
      # 需要生成exe文件的 py。因为可能会有多个入口
      windows = [
        {
          'script':'Login.py',
          # 图标前的索引依赖ico里的图标数
          "icon_resources":[(0, "ui/icon.ico")]
        }
      ],
      data_files = data_files,
      options = OPTIONS,
      # 默认生成一个 library.zip 用来存放打包数据。如果设置为None,则打包数据存放在exe文件里
      zipfile = None,
)
print("打包结束,按任意键退出..") 
msvcrt.getch()

转载于:https://www.cnblogs.com/boliu/p/7580919.html

你可能感兴趣的:([python学习笔记] py2exe 打包)