banner
NEWS LETTER

Pyinstaller IntFlag、vcruntime140.dll及pyttsx3错误的解决办法

Scroll down

在打包程序的时候遇到一大堆报错,查了许久的资料,终于解决.现在整理一下备查.

注:以下内容均来自谷歌,由笔者整理

  • enum.IntFlag

使用pyinstaller编译程序时出现以下错误

1
2
3
4
...
...
class RegexFlag(enum.IntFlag):
AttributeError: module 'enum' has no attribute 'IntFlag'

出现原因: 与tensorflow的enum34库冲突,卸载即可,在需要时再重装

解决办法:

1
pip uninstall enum34
  • vcruntime140.dll

运行程序时出现vcruntime140.dll与系统不兼容的错误

解决办法:关闭upx,在指令中添加如下语句

1
--noupx
  • pyttsx3

这是问题最多的地方
编译使用了pyttsx3的程序后,运行会出现如下错误

1
ModuleNotFoundError: No module named 'pyttsx3.drivers'

解决办法:
在被编译的程序的目录下(理论上任何目录都行)新建目录并新建文件“hook-pyttsx3.py”
(我这里新建“hooks\hook-pyttsx3.py”)
内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#-----------------------------------------------------------------------------
# Copyright (c) 2013-2017, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------


"""
pyttsx3 imports drivers module based on specific platform.
Fount at https://github.com/nateshmbhat/pyttsx3/issues/6
"""


hiddenimports = [
'pyttsx3.drivers',
'pyttsx3.drivers.dummy',
'pyttsx3.drivers.espeak',
'pyttsx3.drivers.nsss',

再在命令行中添加如下参数:
(我在被编译程序根目录执行的pyinstaller,所以用的相对路径“hooks”)

1
--additional-hooks-dir hooks

此时再编译运行出现错误:

1
pywintypes.com_error: (-2147352573, '找不到成员。', None, None)

解决办法:
修改文件“<python路径>\Lib\site-packages\PyInstaller\loader\rthooks\pyi_rth_win32comgenpy.py”
(请阅读后续部分进行操作)
最终效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#-----------------------------------------------------------------------------
# Copyright (c) 2013-2017, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------


# The win32.client.gencache code must be allowed to create the cache in %temp%
# (user's temp). It is necessary to get the gencache code to use a suitable
# directory other than the default in lib\site-packages\win32com\client\gen_py.
# PyInstaller does not provide this directory structure and the frozen
# executable could be placed in a non-writable directory like 'C:\Program Files.
# That's the reason for %temp% directory.
#
# http://www.py2exe.org/index.cgi/UsingEnsureDispatch

import sys
# The win32com fixes aren't needed for Python 3.X
if sys.version_info >= (3, 0):
pass
else:
import atexit
import os
import shutil
import tempfile


# Put gen_py cache in temp directory.
supportdir = tempfile.mkdtemp()
# gen_py has to be put into directory 'gen_py'.
genpydir = os.path.join(supportdir, 'gen_py')


# Create 'gen_py' directory. This directory does not need
# to contain '__init__.py' file.
try:
# win32com gencache cannot be put directly to 'supportdir' with any
# random name. It has to be put in a directory called 'gen_py'.
# This is the reason why to create this directory in supportdir'.
os.makedirs(genpydir)
# Remove temp directory at application exit and ignore any errors.
atexit.register(shutil.rmtree, supportdir, ignore_errors=True)
except OSError:
pass


# Override the default path to gen_py cache.
import win32com
win32com.__gen_path__ = genpydir


# The attribute __loader__ makes module 'pkg_resources' working but On Windows
# it breaks pywin32 (win32com) and test 'basic/test_pyttsx' will fail. Just
# removing that attribute for win32com fixes that and gencache is created properly.
if hasattr(win32com, '__loader__'):
del win32com.__loader__


# Ensure genpydir is in 'gen_py' module paths.
import win32com.gen_py
win32com.gen_py.__path__.insert(0, genpydir)

即在最前面添加版本判断,若python版本大于等于3.0,则不进行处理。后续pyinstaller可能会对该文件进行修改,不建议直接复制,手动添加如下内容即可:

1
2
3
4
5
6
import sys
# The win32com fixes aren't needed for Python 3.X
if sys.version_info >= (3, 0):
pass
else:
<以下为原内容>
其他文章
cover
DDCTF 2019 Writeup
  • 19/04/23
  • 11:28
  • 3.1k
  • 14