如何将Python嵌入Visual Studio C++应用并完成打包部署发布
C++ 内嵌Python应用及资源文件完整部署方案
部署目录结构
最终分发给用户的程序包统一按以下结构组织,避免路径混乱:
YourApp.exe:VS编译生成的C++ GUI可执行文件python/:嵌入式Python运行时根目录python3xx.dll:对应Python版本的核心动态库(如果你已经静态链接Python到exe,可省略该文件)python3xx.zip:Python标准库压缩包(嵌入式发行包自带)Lib/site-packages/:存放所有第三方依赖包,比如你用到的requests及其关联依赖scripts/:存放你自己编写的所有Python业务脚本
resources/:静态资源根目录fonts/:存放所有.ttf字体文件- 图片、配置文件等其他资源可按分类建子目录存放
嵌入式Python运行时配置
嵌入式Python默认开启隔离模式,不会读取用户系统上安装的其他Python环境的包、环境变量,完全依赖打包目录内的文件,不会出现版本冲突,是分发这类应用的首选方案
- 下载和你开发环境版本号、架构(x86/x64)完全一致的Python嵌入式发行包,解压到上述
python目录下 - 修改
python目录下的python3xx._pth文件(xx为你的Python版本号,比如3.10对应python310._pth),配置模块搜索路径,文件内容参考:
python3xx.zip .\Lib .\Lib\site-packages .\scripts .
最后一行的独立
.不能省略,否则Python不会识别当前工作目录的模块,会出现导入失败问题
- 第三方依赖处理:将你开发环境中用到的所有第三方包(比如
requests及其依赖的urllib3、certifi等),从本地Python的site-packages目录完整复制到发布包的python/Lib/site-packages路径下;怕漏依赖可以直接下载对应包的whl压缩包,解压后提取模块文件夹放入即可。
C++端代码适配
你之前硬编码解决方案路径的逻辑只适用于开发阶段,发布时必须改为运行时动态解析路径,避免用户安装路径不同导致找不到文件:
- 先实现获取exe自身所在目录的工具函数,Windows下示例代码:
#include <windows.h> #include <string> std::string GetExeBasePath() { char exePath[MAX_PATH] = {0}; GetModuleFileNameA(NULL, exePath, MAX_PATH); std::string pathStr(exePath); size_t splitPos = pathStr.find_last_of("\\/"); return pathStr.substr(0, splitPos); }
- 在初始化Python解释器之前,主动指定Python运行时根目录,避免默认读取系统Python路径:
std::string exeBase = GetExeBasePath(); std::string pythonHome = exeBase + "\\python"; std::string scriptDir = exeBase + "\\python\\scripts"; std::string fontDir = exeBase + "\\resources\\fonts"; // 转换为Python需要的宽字符路径设置Home std::wstring pyHomeW(pythonHome.begin(), pythonHome.end()); Py_SetPythonHome(const_cast<wchar_t*>(pyHomeW.c_str())); // 初始化解释器 Py_Initialize(); // 双重保险:把自定义脚本目录加入sys.path,避免_pth配置异常 PyObject* sysPath = PySys_GetObject("path"); PyObject* pyScriptPath = PyUnicode_FromString(scriptDir.c_str()); PyList_Append(sysPath, pyScriptPath); Py_DECREF(pyScriptPath);
- 后续导入自定义Python脚本时,直接传脚本文件名即可(不需要带.py后缀),比如脚本名为
data_process.py,直接调用PyImport_ImportModule("data_process")就能正常导入 - 加载ttf字体等资源时,统一用
exeBase拼接相对路径,比如exeBase + "\\resources\\fonts\\your_custom_font.ttf",不管用户把程序安装在哪个磁盘、哪个目录下,都能正确定位文件。
自定义脚本与资源打包注意事项
- 你自己写的.py脚本直接复制到
python/scripts目录即可,不需要额外编译;如果想做简单的防篡改,也可以用py_compile模块编译为.pyc文件后放入,Python运行时会优先加载pyc文件 - 如果Python脚本内部有文件读取逻辑,不要写硬编码路径,用Python内置的
__file__变量获取脚本自身所在目录后拼接相对路径,和C++端的路径逻辑保持一致 - 测试发布包时不要在开发机的项目目录下运行,把整个发布包复制到没有安装对应版本Python的干净虚拟机/测试机上验证,确保所有模块导入、资源加载都正常,避免开发环境污染导致的测试误判。
可选优化项
- 如果不想让自定义脚本散落在目录中,可以把所有.py脚本打包成一个zip压缩包,把该zip包的路径加入Python的sys.path,Python原生支持直接从zip包导入模块
- ttf字体等资源如果不想单独存放,也可以作为自定义资源嵌入到exe的资源段中,程序启动时释放到临时目录加载,日常使用场景下单独放resources目录维护成本更低
- 最终分发时可以用Inno Setup、NSIS等安装包制作工具,把整个目录结构打包为单文件安装程序,用户点击下一步即可完成安装,不需要手动解压复制文件。
内容的提问来源于stack exchange,提问作者levente.nas
相关产品推荐
相关产品推荐

