最近做了一个使用tensorflow的机器学习项目,需要将Python的代码经过编译形成一个exe文件,一方面方便用户使用,另一方面可以隐藏自己的源码,一定程度上减少代码泄露的风险。(注意:可以使用ctrl + F
搜索你所遇到的错误)
环境:Windows 10 专业版
,Python 3.6.6 64位
常见的将Python封装成exe文件的方法有:
pyinstaller的封装方式较为简便,命令行中执行命令
pyinstaller -D xxx.py
即可将Python文件转换为exe文件,以及dist文件夹和build文件夹,如果要移植到其他电脑上运行,也是只需要将这两个文件夹复制到对方电脑上,即使对方没有python环境,也可以运行程序,具有较好的兼容性。
缺点就是,安全性不高,容易被反编译。
此处用到的工具:
exe反编译工具:pyinstxtractor.py:exe反编译工具下载
pyc反编译工具:Easy Python Decompiler 或者在线反编译pyc。
将pyinstxtractor.py放到exe文件相同目录,执行以下cmd命令:
python pyinstxtractor.py main.exe
详细请参照【PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译】
Nuitka安全性较高,且根据用户反映能够提升代码执行效率。
cmd中执行命令:
nuitka --recurse-all xxx.py
但是Nuitka的使用难度也较大,网络上的教程也很少,且存在无法运行PyQt5这个UI界面的缺陷,所以最终放弃使用Nuitka。
如上一节所述,上面的两种方法不能满足我对项目打包的要求,于是考虑其他方法,先通过Cython将Python转为.c文件,再通过C语言编译器,将C语言转为.exe文件,此时的文件相较于pyinstaller的生成的exe文件就具有了更强的反编译能力。
搭建好Python环境后,在cmd输入一下命令并执行:
pip install Cython
安装完Cython后,命令行进入到目标Python文件xxx.py的目录下,执行命令:
cython xxx.py --embed
报错如下
Error compiling Cython file:
------------------------------------------------------------
...
import sys
^
------------------------------------------------------------
software_V1.5.py:1:0: 'software_V1.5' is not a valid module name
这个错误是因为文件software_V1.5.py
命名中出现多余的'.'
,解决的方式是去除这个多余的'.'
,可将文件名改为software_V15.py
即可解决错误。
PS C:\User> cython .\software_V15.py
c:Users\yww\AppData\Local\Programs\Python\python36\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\User\software_V15.py
tree = Parsing.p_module(s, pxd, full_module_name)
PS C:\User>
运行成功,生成C文件,但是这个警告不知道是什么意思,但是不影响后面的工作。
参考【使用cython,gcc将python转换为.exe可执行文件】,进行完第二节的步骤,在刚刚转换得到的c文件的目录下,执行cmd命令:
gcc xxx.c -o xxx.exe
结果报错“fatal error: Python.h: No such file or directory”
PS C:\User> gcc .\software_V15.c -o .\software_V15.exe
.\software_V15.c:4:10: fatal error: Python.h: No such file or directory
#include "Python.h"
^~~~~~~~~~
compilation terminated.
首先尝试将python路径下的'incloud'
目录加入到环境变量的Path中,使得生成的C文件可以调用其中.h文件,还是报同样的错误。然后尝试网上的方法,安装python-dev
。但是python-dev
只有Linux系统可以使用:
1. sudo apt-get install aptitude
2. sudo aptitude install python-dev
进行安装,而Windows没有找到安装包。最终,在发现cl.exe
编译器之后,选择放弃gcc编译。
安装安装Microsoft Visual C++ Build Tools 2015
,【Microsoft Visual C++ Build Tools 2015 下载地址】
滑动至页面下方进行下载:
安装Windows 10 SDK
,【Windows 10 SDK 下载地址】
下载后直接点击,默认安装。
安装完毕后配置环境变量。在环境变量中寻找变量Path、include、lib
,如果没有点击新建进行创建,配置时要注意区分Python是64位还是32位
,我的Python是64位
的。
(1) Path
在64位Python下添加的路径:
C:\Users\yww\AppData\Local\Programs\Python\python36
C:\Users\yww\AppData\Local\Programs\Python\python36\include
C:\Users\yww\AppData\Local\Programs\Python\python36\Scripts
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE
C:\Program Files (x86)\Windows Kits\10\bin\x64
(2) include
在64位Python下添加的路径:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
C:\Program Files (x86)\Windows Kits\8.1\Include\um
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared
C:\Users\yww\AppData\Local\Programs\Python\python36\include
(3)lib
在64位Python下添加的路径:
C:\Users\yww\AppData\Local\Programs\Python\python36\libs
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\x64
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64
如果你使用的Python是32位
,将上面的amd64
或者x64
,改为目录下x86
系列目录即可,32位
cl.exe的目录为:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
注意,上面Python的路径是我的电脑上Python的路径,要根据你们Python的路径进行配置。安装完成后,转换得到的C文件目录下执行:
cl -GX xxx.c
得到:
PS C:\User> cl -GX .\software_V15.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
cl : Command line warning D9035 : option 'GX' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'EHsc' instead of 'GX'
software_V15.c
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:software_V15.exe
software_V15.obj
Creating library software_V15.lib and object software_V15.exp
PS C:\User>
成功生成exe文件!
(1) LINK : fatal error LNK1561: entry point must be defined
错误如下:
PS C:\User> cl -GX .\software_V15.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
cl : Command line warning D9035 : option 'GX' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'EHsc' instead of 'GX'
software_V15.c
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:software_V15.exe
software_V15.obj
Creating library software_V15.lib and object software_V15.exp
LINK : fatal error LNK1561: entry point must be defined
C:\User>
这个时候不能生成exe文件,这是由于在使用Cython将Python转为C时,将
cython xxx.py --embed
写成
cython xxx.py
这个错误的原因是在执行Cython时,未使用--embed
关键字,导致生成的C文件中没有main函数。
(2) fatal error C1083: 无法打开包括文件: “io.h”: No such file or directory
除了io.h,还会出现找不到其他.h、.lib文件的情况,这是因为没有配置好环境变量,重新按照3.2
部分配置环境变量。
(3) fatal error LNK1112: module machine type ‘x64’ conflicts with target machine type 'X86’
PS C:\User> cl -GX .\software_V15.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
cl : Command line warning D9035 : option 'GX' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'EHsc' instead of 'GX'
software_V15.c
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:software_V15.exe
software_V15.obj
python36.lib(python36.dll) : fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
C:\User>
这个是由于cl.exe
的位数与Python的位数不匹配,需要查看你所使用Python的位数(如64位Python),并以此根据3.2
进行环境变量配置。
要在其他电脑上运行,需要搭建环境。首先在需要运行的电脑上安装Python,这个教程很多,不再赘述,但是要注意Python的位数(64位
还是32位
)。【Python下载地址】
还有一个需要注意的是,目标电脑Python的安装路径需要和你的电脑中Python的安装路径一致,否则也会报错。
安装好Python后,从你的电脑Python路径下Lib
目录中,打包site-packages
,并将这个文件传输到目标电脑中同样的Python目录下,替换原来的文件。
将生成的.exe
文件以及同级目录下的build
文件夹打包(如果有权重文件,则对其进行加密后也要一起打包)。然后将这个包传输至目标电脑中进行解压。至此,就可以顺利在目标电脑上运行你的exe文件了。
这种将Python文件先转换成.c
文件在转换为.exe
文件的方式,不能使用针对python的反编译软件进行反编译,例如之前介绍的pyinstxtractor.py
,整体安全性要比使用Pyinstaller直接加密要高,具有一定的破解难度。且相比pyinstaller生成接近1G的包相比,使用这种方式生成的包只有50M。特别的轻量化。
第一次写的博客,感谢朋友对我的帮助,也特别希望各位大佬能对这种打包方式给出意见和建议,最重要的是想知道这种方式是否真的如我想象的这样安全。