dil*_*ert 13 python pyinstaller
我正在尝试使用pyInstaller打包一个wxpython应用程序.我正在寻找"单文件夹"模式的变体,其中dll和pyds不存储在顶级目录中,而是存储在子目录中(如"dlls"或"libs").
这是当前的spec文件:
# -*- mode: python -*-
import os
a = Analysis\
(
["..\\job_scraper\\load_gui.py"],
pathex = ["C:\\Users\\Administrator\\Documents\\Projects\\python\\PyInstaller\\load_gui"],
hiddenimports = [],
hookspath = None,
runtime_hooks = None
)
a_binaries = []
for (name, path, data_type) in a.binaries:
(non_ext, ext) = os.path.splitext(name)
if(ext in [".pyd", ".dll"]):
a_binaries.append((os.path.join("libs", name), path, data_type))
else:
a_binaries.append((name, path, data_type))
a.binaries = TOC(a_binaries)
pyz = PYZ(a.pure)
exe = EXE\
(
pyz,
a.scripts,
exclude_binaries = True,
name = "load_gui.exe",
debug = False,
strip = None,
upx = True,
console = False
)
coll = COLLECT\
(
exe,
a.binaries,
a.zipfiles,
a.datas,
[("control.csv", "..\\job_scraper\\control.csv", "DATA")],
strip = None,
upx = True,
name = "load_gui"
)
Run Code Online (Sandbox Code Playgroud)
这样做可以将dll(而不是pyds)放入lib文件夹中,但是它似乎在链接后执行此操作,因此程序无法启动,因为它无法找到预期的dll.
问题是不sys.path包括您的子目录。因此,当程序运行时,它不知道在哪里查找 .dll 或 .pyd 文件。
sys.path.append("relative/path/to/your/subdirectories")当然,我会想到将代码放在主脚本之上。但再次强调,此代码仅在所有内容都加载并就位后执行。
根据此博客,解决方案是使用 pyinstaller 的运行时挂钩。运行时挂钩告诉引导代码在主脚本运行之前运行任何任意代码 - 在导入任何内容之前。
创建一个hooker.py将所有自定义路径添加到sys.path. 将其放在某处并仅执行 1 次。
import sys
import os
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), "lib")) # for pyd
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), "windll")) # for dll
Run Code Online (Sandbox Code Playgroud)
与规格文件:
a = Analysis\
(
["..\\job_scraper\\load_gui.py"],
pathex = ["C:\\Users\\Administrator\\Documents\\Projects\\python\\PyInstaller\\load_gui"],
hiddenimports = [],
hookspath = None,
runtime_hooks = "absolute/path/to/hooker.py" # <----- add it here
)
Run Code Online (Sandbox Code Playgroud)
或使用命令行:
pyinstaller --runtime-hook="absolute/path/to/hooker.py" the_rest_parameters
像往常一样,它将创建dist/your_main_script_name包含文件、清单、library.zip和exe一堆.dll.pyd
现在您可以创建一个windll文件夹和lib/或在步骤 1 中添加的任何内容。sys.path然后将所有.pyd文件移至lib以及将所有.dll文件移至windll。
运行你的exe,它会崩溃!因此,将以下文件移回父文件夹。
引导程序需要这些文件,因此我们无法在不修改引导程序代码的情况下移动它们。
再次运行exe,应该可以正常工作了。
很快你就会厌倦一遍又一遍地重复上述所有事情。这就是我一直在做的事情。
compiler.bat使用类似于以下内容的内容进行创建:
pyinstaller --runtime-hook="absolute/path/to/hooker.py" --onedir --icon path/to/icon ^
--exclude-module=UnNeeded_module_A ^
--exclude-module=UnNeeded_module_B ^
%1
@echo off
for %%F in (%1) do set pyi_output=%%~nxF
set pyi_output=%pyi_output:~0,-3%
mkdir dist\%pyi_output%\windll
mkdir dist\%pyi_output%\lib
move dist\%pyi_output%\*.dll dist\%pyi_output%\windll
move dist\%pyi_output%\*.pyd dist\%pyi_output%\lib
move dist\%pyi_output%\windll\python36.dll dist\%pyi_output%
move dist\%pyi_output%\windll\VCRUNTIME140.dll dist\%pyi_output%
if exist dist\%pyi_output%\windll\pywintypes36.dll (
move dist\%pyi_output%\windll\pywintypes36.dll dist\%pyi_output%
)
pause
Run Code Online (Sandbox Code Playgroud)
为了不搞乱您的项目,请创建代码文件夹的副本并将其放入compile.bat其中。然后,只需将其拖放main_script.py到compile.bat.
该pause命令使控制台窗口保持打开状态,以便您知道编译是否成功。
小智 -4
另一种方式,新的 loadmyapp.c:
#include<stdlib.h>
main(int argc,char *argv[]) {
execv("yourapp/app.exe", argv);
}
Run Code Online (Sandbox Code Playgroud)
gcc -o loadmyapp loadmyapp.c
./loadmyapp
| 归档时间: |
|
| 查看次数: |
1977 次 |
| 最近记录: |