java打包python到exe文件

最近想把写的python代码打包,以供没用安装python环境的同事使用,需求如下: 
  • 无python环境也可执行
  • 文件尽量少,不要太乱
  • 程序体积尽量小
  • 如果需要更新的话重复类库不用更新

采用方案如下: 
  • 使用py2exe自动导入类库
  • 使用7-ZIP压缩library
  • upx压缩dll等文件
  • nsis生成安装文件
  • 采用md5验证的方式判别不用更新的类库


使用py2exe自动导入类库 
建立文件bin_setup.py 
Python代码    收藏代码
  1. #!/usr/bin/env python  
  2. # -*- coding: utf-8 -*-  
  3.   
  4. __author__ = 'lxd'  
  5.   
  6. from distutils.core import setup    
  7. import py2exe    
  8. import sys  
  9.   
  10. # If run without args, build executables, in quiet mode.  
  11. if len(sys.argv) == 1:  
  12.     sys.argv.append("py2exe")  
  13.     sys.argv.append("-q")  
  14.   
  15. INCLUDES = []  
  16.   
  17. MANIFEST_TEMPLATE = """ 
  18. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
  19. <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
  20.   <assemblyIdentity 
  21.     version="5.0.0.0" 
  22.     processorArchitecture="x86" 
  23.     name="%(prog)s" 
  24.     type="win32" 
  25.   /> 
  26.   <description>%(prog)s</description> 
  27.   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
  28.     <security> 
  29.       <requestedPrivileges> 
  30.         <requestedExecutionLevel 
  31.             level="asInvoker" 
  32.             uiAccess="false"> 
  33.         </requestedExecutionLevel> 
  34.       </requestedPrivileges> 
  35.     </security> 
  36.   </trustInfo> 
  37.   <dependency> 
  38.     <dependentAssembly> 
  39.       <assemblyIdentity 
  40.             type="win32" 
  41.             name="Microsoft.VC90.CRT" 
  42.             version="9.0.21022.8" 
  43.             processorArchitecture="x86" 
  44.             publicKeyToken="1fc8b3b9a1e18e3b"> 
  45.       </assemblyIdentity> 
  46.     </dependentAssembly> 
  47.   </dependency> 
  48.   <dependency> 
  49.     <dependentAssembly> 
  50.         <assemblyIdentity 
  51.             type="win32" 
  52.             name="Microsoft.Windows.Common-Controls" 
  53.             version="6.0.0.0" 
  54.             processorArchitecture="X86" 
  55.             publicKeyToken="6595b64144ccf1df" 
  56.             language="*" 
  57.         /> 
  58.     </dependentAssembly> 
  59.   </dependency> 
  60. </assembly> 
  61. """  
  62. RT_MANIFEST = 24  
  63.   
  64. options = {"py2exe" :  
  65.     {"compressed" : 1,  
  66.      "optimize" : 2,  
  67.      "bundle_files" : 2,  
  68.      "includes" : INCLUDES,  
  69.      "excludes" : ["Tkinter",],  
  70.      "dll_excludes": [ "MSVCP90.dll", "mswsock.dll", "powrprof.dll"] }}  
  71.   
  72. windows = [{"script": "bin.py",  
  73.       "icon_resources": [(1, "bin.ico")],  
  74.       "other_resources" : [(RT_MANIFEST, 1,  
  75.                         MANIFEST_TEMPLATE % dict(prog="MyAppName"))],  
  76.       }]  
  77.   
  78. setup(name = "MyApp",  
  79.       version = "1.0",  
  80.       description = "Description of the app",  
  81.       author = "Author Name",  
  82.       author_email ="[email protected]",  
  83.       maintainer = "Maintainer Name",  
  84.       maintainer_email = "[email protected]",  
  85.       license = "wxWindows Licence",  
  86.       url = "http://projecthomepage.com",  
  87.   
  88.       data_files = ["MSVCR90.dll", "gdiplus.dll"],  
  89.       #data_files=[("img",[r"d:\test\1.gif",r"d:\test\2.gif"]),("xml",[r"d:\test\1.xml",r"d:\test\2.xml"])])  
  90.       #zipfile=None,  
  91.       options = options,  
  92.       windows = windows,  
  93.       )  

使用7-ZIP压缩library,使用upx压缩dll等文件 
建立脚本bin.cmd 
Java代码    收藏代码
  1. @echo off  
  2.   
  3. ::Set personal Path to the Apps:  
  4. set PythonEXE=D:\Python26\python.exe  
  5. set SevenZipEXE="D:\Program Files\7-ZIP\7z.exe"  
  6. set UpxEXE="D:\Program Files\upx\upx.exe"  
  7.   
  8. :: Compress=1 - Use CompressFiles  
  9. :: Compress=0 - Don't CompressFiles  
  10. set Compress=1  
  11.   
  12. if not exist %~dpn0.py          call :FileNotFound %~dpn0.py  
  13. if not exist %PythonEXE%        call :FileNotFound %PythonEXE%  
  14. if not exist %SevenZipEXE%      call :FileNotFound %SevenZipEXE%  
  15. if not exist %UpxEXE%           call :FileNotFound %UpxEXE%  
  16.   
  17. ::Compile the Python-Script  
  18. %PythonEXE% "%~dpn0_setup.py" py2exe  
  19. if not "%errorlevel%"=="0" (  
  20.         echo Py2EXE Error!  
  21.         pause  
  22.         goto:eof  
  23. )  
  24.   
  25. :: Copy the Py2EXE Results to the SubDirectory and Clean Py2EXE-Results  
  26. rd build /s /q  
  27. xcopy dist\*.* "%~dpn0_EXE\" /d /y  
  28. :: I use xcopy dist\*.* "%~dpn0_EXE\" /s /d /y  
  29. :: This is necessary when you have subdirectories - like when you use Tkinter  
  30. rd dist /s /q  
  31.   
  32. if "%Compress%"=="1" call:CompressFiles  
  33. echo.  
  34. echo.  
  35. echo Done: "%~dpn0_EXE\"  
  36. echo.  
  37. pause  
  38. goto:eof  
  39.   
  40. :CompressFiles  
  41.         %SevenZipEXE% -aoa x "%~dpn0_EXE\library.zip" -o"%~dpn0_EXE\library\"  
  42.         del "%~dpn0_EXE\library.zip"  
  43.   
  44.         cd %~dpn0_EXE\library\  
  45.         %SevenZipEXE% a -tzip -mx9 "..\library.zip" -r  
  46.         cd..  
  47.         rd "%~dpn0_EXE\library" /s /q  
  48.   
  49.         cd %~dpn0_EXE\  
  50.         %UpxEXE% --best *.*  
  51. goto:eof  
  52.   
  53. :FileNotFound  
  54.         echo.  
  55.         echo Error, File not found:  
  56.         echo [%1]  
  57.         echo.  
  58.         echo Check Path in %~nx0???  
  59.         echo.  
  60.         pause  
  61.         exit  
  62. goto:eof  

使用方法: 
直接运行bin.cmd,程序会自动调用bin_setup.py来查找需要的类库,然后对类库文件进行压缩,生成的可执行文件在bin_EXE里。 
问题: 
我在打包的时候,出现错误“ImportError: MemoryLoadLibrary failed loading win32api.pyd”,用depends.exe查看其引用,然后多方搜索得知,其原因是py2exe错误的加载了mswsock.dll,powrprof.dll这两个文件,因此将它们排除即可。 
Python代码    收藏代码
  1. "dll_excludes": [ "MSVCP90.dll", "mswsock.dll", "powrprof.dll"] }}  

nsis生成安装文件 
待续。。。 

 

你可能感兴趣的:(python)