py2exe 打包含有apscheduler(定时任务框架)后的exe运行出错

因为py2exe打包的时候会自动根据你代码中的引用把资源给打包进来,可是凡事不是绝对的,代码中可能会有隐形的引入了其余的py文件或资源文件的时候是没法自动识别的,因此就须要手动的配置,或者作一些手动操做了,还有也能够在本身代码中先把隐形的引入用显式的引入把py文件导入好比:python

# 这个是打包apscheduler确实存在的问题,后面两个是由于后面的问题而引入的
from apscheduler.triggers.cron import * from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.date import DateTrigger

最早我遇到的问题是打包后打开exe后报错:pkg_resources.DistributionNotFound: APScheduler,这个问题搜了好久都没找到解决方案,后来硬着头皮看了下源代码,发现apscheduler/__init__.py里面代码是这样的:git

# These will be removed in APScheduler 4.0.
release = __import__('pkg_resources').get_distribution('APScheduler').version.split('-')[0]
version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.'))
version = __version__ = '.'.join(str(x) for x in version_info[:3])

 

  发如今打包后的发现多是没有把APScheduler-3.3.0.dist-info资源文件打包进来致使get_distribution('APScheduler')报错了,我想这个文件好像没什么实质做用啊,而后这段代码就是为了获取apscheduler的版本号用的,因此我就把这里面的代码所有注释了,而后打包后打开exe不报这个错了,并且原来的功能也没问题,因此这应该也算是解决方法之一吧。json

  但这个以后有报错:pytz.exceptions.UnknownTimeZoneError: 'Asia/Shanghai',这个我也跟了下源码,发现打包的时候又缺乏文件,我那个汗。。。windows

  这个有两个方法:api

  1. 手动复制这个zoneinfo文件到打包后的library.zip/pytz下
  2. 本身在setup.py里面写代码复制过来

  总之把文件拷贝过来就对了,具体代码下面会上,请往下看blog

 

  可是其余的资源文件,一、图片、文本类型等的非第三方库的文件  二、第三方库文件图片

若是是第一种状况能够在setup中这样配置下便可:ip

setup(windows=["main.py"],
      options={"py2exe": {
          'packages': ['pytz']
      }},
      # 静态资源文件路径配置
      data_files=[("img", ["img/picon.ico"]),
                  ("config", ["config/config.json"])])

若是是第二种状况就要麻烦点了:utf-8

# coding=utf-8
__author__ = 'carlos'
from distutils.core import setup

import py2exe

setup(windows=["main.py"],
      options={"py2exe": {
          'packages': ['pytz']
      }},
      # 静态资源文件路径配置
      data_files=[("img", ["img/picon.ico"]),
                  ("config", ["config/config.json"])])

# 打包pytz时候缺乏文件zoneinfo里的全部文件,这里是手动添加回去了
import pytz
import os
import zipfile
zipfile_path = os.path.join("dist/" 'library.zip')
z = zipfile.ZipFile(zipfile_path, 'a')
zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo')
disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__))
for absdir, directories, filenames in os.walk(zoneinfo_dir):
    assert absdir.startswith(disk_basedir), (absdir, disk_basedir)
    zip_dir = absdir[len(disk_basedir):]
    for f in filenames:
      z.write(os.path.join(absdir, f), os.path.join(zip_dir, f))

z.close()

或者本身手动复制这个zoneinfo文件到打包后的library.zip/pytz下。这个是打包含有pytz库的时候会有这个问题,其余若是打包遇到了此问题能够往这条路上看看,也许就是这个问题,哈哈^^!资源

可是打包后仍是报错:No trigger by the name "interval" was found,网上搜了下这个答案就比较多了,缘由以下:

原来的代码是:

self.scheduler.add_job(self.DoCmd, item.get('trigger'), args=(item.get('cmd'), item.get('name')), **params)

修改成:

trigger_name = '%s%s' % (item.get('trigger').capitalize(), 'Trigger')
trigger = eval(trigger_name)(**params)
self.scheduler.add_job(self.DoCmd, trigger, args=(item.get('cmd'), item.get('name')))

由于用到了IntervalTrigger, CronTrigger和DateTrigger因此上面引入了,哎呀妈呀,一个接一个问题,不得不说py2exe也不能这么智能啊,总会有这么多问题,其实我也看过其余的打包方法好比pyinstaller和cx_Freeze都有这些问题,想一想看应该也是的,有些非直接的引路很难查询到,可能大牛能够吧,反正至少我没这个功底能办到呵呵...

这里提示下初次用py2exe的人,也给本身提个醒以防本身忘记:

py2exe打包在不一样win环境下打出来的包不是能够运用于全部的win环境的,好比我再win10中打包出来的放在某些xp下就不能运行,应该是缺乏一些dll文件,若是遇到这类问题试试在xp底下打包,可能能够解决这个问题。

相关文章
相关标签/搜索