PyInstaller 是开源的,可以对其深度订制(改进 Bootloader)。 PyInstaller Manual
遇到的最大问题就是启动慢的问题。
每次都会生成临时文件夹并释放文件,有点烦人。如果崩溃了,临时文件就残留了。本文尝试修改启动器,改掉这个问题。
This can be done using the --runtime-tmpdir
option.
我的调整:hawkhai / pyinstaller
(还未完成)
pip install --upgrade pyinstaller
#!/usr/bin/env python3
import sys, os
frozen = 'not'
if getattr(sys, 'frozen', False):
# we are running in a bundle
frozen = 'ever so'
bundle_dir = sys._MEIPASS
else:
# we are running in a normal Python environment
bundle_dir = os.path.dirname(os.path.abspath(__file__))
print( 'we are', frozen, 'frozen' )
print( 'bundle dir is', bundle_dir )
print( 'sys.argv[0] is', sys.argv[0] )
print( 'sys.executable is', sys.executable )
print( 'os.getcwd is', os.getcwd() )
这里 描述详细的启动过程。
双进程实现(除了 Windows one-folder 模式)。
temppath/_MEIxxxxxx
。temppath/_MEIxxxxxx
。python ./waf all
python ./waf all --target-arch=32bit
不能对现有流程造成影响,保持将来的升级能力。 把附加配置通过后期资源打到最终 pe 文件里面。 然后 Bootloader 读取配置。
pyi_launch_need_to_extract_binaries
swprintf(prefix, 16, L"_MEI%d", getpid());
– 这里一个固定的版本号接上去。pyi_get_temp_path
pyi_create_temp_path
pyi_launch_extract_binaries
pyi_arch_extract2fs(ARCHIVE_STATUS *status, TOC *ptoc)
pyi_remove_temp_path
python pyinstxtractor.py xx.exe
uncompyle6
set CL=-FI"Full-Path\stdint.h" (use real value for Full-Path for the environment)
pip install pycrypto
pyinstaller.exe -F --key 123456 xxx.py
$ conda create -n my-py3.6-environment python=3.6
$ conda activate my-py3.6-environment
pipenv install
[[source]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
verify_ssl = true
name = "pypi"
# 把 pyinstaller 安装到开发环境中
pipenv install pyinstaller --dev
# 进入虚拟环境
pipenv shell
import os
import sys
os.chdir(os.path.dirname(__file__))
sys.path.append("..")
import settings
# 直接运行 js 代码
import js2py
context = js2py.EvalJs()
with open("./ids-encrypt.js") as f:
js_content = f.read()
def encryptAES(data, salt):
# 执行整段 JS 代码
context.execute(js_content)
result = context.encryptAES(data, salt)
return result
# 通过清华镜像源,下载快
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple uncompyle
uncompyle test.pyc > test.py
https://pyob.oxyry.com/ https://blog.csdn.net/ir0nf1st/article/details/61650984
def obfuscation(py_file, save_path):
print("读取文件:", py_file)
with open(py_file, "r", encoding="utf-8") as f:
py_content = f.read()
print("进行混淆中 ...")
url = "https://pyob.oxyry.com/obfuscate"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
"Referer": "http://pyob.oxyry.com/",
"content-type": "application/json",
"cookie": "_ga=GA1.2.1306886713.1588752647; _gid=GA1.2.46944674.1588899118"
}
data = json.dumps({
"append_source": "false",
"preserve": "",
"remove_docstrings": "true",
"rename_default_parameters": "false",
"rename_nondefault_parameters": "true",
"source": py_content
})
result = json.loads(requests.post(url, data=data, headers=headers).text)["dest"]
result = "# cython: language_level=3\n" + result
print("混淆成功 ...")
with open(save_path, "w", encoding="utf-8") as f:
f.write(result)
print("混淆文件已写入 {}\n".format(save_path))
if __name__ == '__main__':
obfuscation("my.py", "../ 混淆 /my.py")
obfuscation("approach.py", "../ 混淆 /approach.py")
编译 pyd
build_pyd.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
name='any words.....',
ext_modules=cythonize(["my.py","approach.py" ])
)
import json
import os
# 清理旧 pyd 文件
import uuid
import requests
def clearPyd():
for file in os.listdir():
if ".pyd" in file:
print("删除 .pyd:", file)
os.remove(file)
print("***********************************************************************")
# 构建 pyd 文件
def buildPyd():
os.system("python build_pyd.py build_ext --inplace")
# 重命名 pyd 文件
def renamePyd():
print("***********************************************************************")
for file in os.listdir():
if ".pyd" in file:
print("重新命名 pyd:", file)
os.rename(file, file[:file.find(".")] + ".pyd")
for file in os.listdir():
if ".c" in file:
print("删除 .c 文件:", file)
os.remove(file)
print("***********************************************************************")
# 执行打包
def pyinstaller(key, ico):
os.system("pyinstaller -F --key {} -i {} main.py".format(key, ico))
# 删除 bulid 和 spec 文件
def clearBuildAndSpec():
import shutil
shutil.rmtree('build')
print("删除 bulid 文件夹")
os.remove("main.spec")
print("删除 spec 文件")
if __name__ == '__main__':
clearPyd() # 清理旧 pyd 文件
buildPyd() # 构建 pyd 文件
renamePyd() # 重命名 pyd 文件
pyinstaller(uuid.uuid4()[0:16], "1.ico") # 执行打包
clearPyd() # 清理 pyd 文件
clearBuildAndSpec() # 删除 bulid 和 spec 文件
sys.stdout.buffer.write('\u5000'.encode('utf8'))
https://stackoverflow.com/questions/44780476/windows-cmd-piping-python-3-5-py-file-results-works-but-pyinstaller-exes-leads https://github.com/chriskiehl/Gooey/issues/520 https://blog.csdn.net/hello_crayon/article/details/80940390
# determine if application is a script file or frozen exe
if getattr(sys, 'frozen', False):
PATH_CUR = os.path.dirname(sys.executable)
elif __file__:
PATH_CUR = os.path.dirname(__file__)
sys.stdout.reconfigure(encoding='utf-8')
sys.stdin.reconfigure(encoding='utf-8')
import codecs
if sys.stdout.encoding != 'UTF-8':
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict')
if sys.stderr.encoding != 'UTF-8':
sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict')
https://www.cnblogs.com/MMLoveMeMM/articles/3811166.html
貌似不同 python 版本打包出来的文件不能混用一个文件夹。 https://juejin.cn/s/python%20failed%20to%20execute%20script%20pyi_rth_win32comgenpy loader2.exe 多余的文件要重命名。