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底下打包,可能能夠解決這個問題。

相關文章
相關標籤/搜索