遵照 http://www.tribler.org/trac/wiki/BrowserPlugin 中对SwarmPlugin的说明,首先需要编译出BG Process这个东东。
下载源码 svn co http://svn.tribler.org/abc/branches/mainbranch/,将源码放到你自己指定路径后执行C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe Traceback (most recent call last): File "Tribler\Plugin\Build\Win32\setupBGexe.py", line 8, in <module> import py2exe # Not a superfluous import! ImportError: No module named py2exe提示缺少py2exe模块,从SourceForge上下载py2exe-0.6.9.win32-py2.7.exe并安装到默认路径C:\Python27\Lib\site-packages\
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe running py2exe creating C:\Python27\build creating C:\Python27\build\bdist.win32 creating C:\Python27\build\bdist.win32\winexe creating C:\Python27\build\bdist.win32\winexe\collect-2.7 creating C:\Python27\build\bdist.win32\winexe\bundle-2.7 creating C:\Python27\build\bdist.win32\winexe\temp creating C:\Python27\dist *** searching for required modules *** C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration global START_TIME *** parsing results *** creating python loader for extension 'vlc' (C:\Python27\vlc.pyd -> vlc.pyd) creating python loader for extension 'unicodedata' (C:\Python27\DLLs\unicodedata.pyd -> unicodedata.pyd) creating python loader for extension 'win32pdh' (C:\Python27\lib\site-packages\win32\win32pdh.pyd -> win32pdh.pyd) creating python loader for extension '_ctypes' (C:\Python27\DLLs\_ctypes.pyd -> _ctypes.pyd) creating python loader for extension 'select' (C:\Python27\DLLs\select.pyd -> select.pyd) creating python loader for extension 'win32event' (C:\Python27\lib\site-packages\win32\win32event.pyd -> win32event.pyd) creating python loader for extension 'wx._controls_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_controls_.pyd -> wx._co ntrols_.pyd) creating python loader for extension 'apsw' (C:\Python27\lib\site-packages\apsw.pyd -> apsw.pyd) creating python loader for extension 'win32evtlog' (C:\Python27\lib\site-packages\win32\win32evtlog.pyd -> win32evtlog.pyd) creating python loader for extension 'win32file' (C:\Python27\lib\site-packages\win32\win32file.pyd -> win32file.pyd) creating python loader for extension 'wx._windows_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_windows_.pyd -> wx._wind ows_.pyd) creating python loader for extension '_hashlib' (C:\Python27\DLLs\_hashlib.pyd -> _hashlib.pyd) creating python loader for extension 'bz2' (C:\Python27\DLLs\bz2.pyd -> bz2.pyd) creating python loader for extension '_ssl' (C:\Python27\DLLs\_ssl.pyd -> _ssl.pyd) creating python loader for extension '_sqlite3' (C:\Python27\DLLs\_sqlite3.pyd -> _sqlite3.pyd) creating python loader for extension 'wx._core_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core_.pyd -> wx._core_.pyd) creating python loader for extension 'wx._misc_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_misc_.pyd -> wx._misc_.pyd) creating python loader for extension 'wx._xrc' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_xrc.pyd -> wx._xrc.pyd) creating python loader for extension 'M2Crypto.__m2crypto' (C:\Python27\lib\site-packages\M2Crypto\__m2crypto.pyd -> M2Crypto.__m2 crypto.pyd) creating python loader for extension '_win32sysloader' (C:\Python27\lib\site-packages\win32\_win32sysloader.pyd -> _win32sysloader .pyd) creating python loader for extension 'wx._gdi_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_gdi_.pyd -> wx._gdi_.pyd) creating python loader for extension 'pyexpat' (C:\Python27\DLLs\pyexpat.pyd -> pyexpat.pyd) creating python loader for extension 'win32ui' (C:\Python27\lib\site-packages\Pythonwin\win32ui.pyd -> win32ui.pyd) creating python loader for extension 'win32api' (C:\Python27\lib\site-packages\win32\win32api.pyd -> win32api.pyd) creating python loader for extension '_socket' (C:\Python27\DLLs\_socket.pyd -> _socket.pyd) *** finding dlls needed *** error: python25.dll: No such file or directory本人装的python版本为2.7.3,这里报没有找到python25.dll,奇怪,没办法,只好分析源码。
import os from distutils.core import setup import py2exe # Not a superfluous import! from Tribler.__init__ import LIBRARYNAME mainfile = os.path.join(LIBRARYNAME,'Plugin','SwarmEngine.py') # Arno: 2009-06-09: changed from console= to make sure py2exe writes # a BackgroundProcess.exe.log # setup(windows=[mainfile])再查看py2exe包的__init__.py文件
# py2exe/__init__.py # 'import py2exe' imports this package, and two magic things happen: # # - the 'py2exe.build_exe' submodule is imported and installed as # 'distutils.commands.py2exe' command # # - the default distutils Distribution class is replaced by the # special one contained in this module. # __version__ = "0.6.9" import distutils.dist, distutils.core, distutils.command, build_exe, sys class Distribution(distutils.dist.Distribution): def __init__(self, attrs): self.ctypes_com_server = attrs.pop("ctypes_com_server", []) self.com_server = attrs.pop("com_server", []) self.service = attrs.pop("service", []) self.windows = attrs.pop("windows", []) self.console = attrs.pop("console", []) self.isapi = attrs.pop("isapi", []) self.zipfile = attrs.pop("zipfile", "library.zip") distutils.dist.Distribution.__init__(self, attrs) distutils.core.Distribution = Distribution distutils.command.__all__.append('py2exe') sys.modules['distutils.command.py2exe'] = build_exe由注释可以看出,该文件干了两件事,其中导入build_exe作为py2exe是和我相关的,于是查看build_exe文件。在该文件中能够找到上面出错的最后一行打印的对应代码 print "*** finding dlls needed ***"。
...... def bin_depends(path, images, excluded_dlls): import py2exe_util warnings = FileSet() images = FileSet(images) dependents = FileSet() others = FileSet() while images: for image in images.copy(): images.remove(image) if not image in dependents: dependents.add(image) abs_image = os.path.abspath(image) loadpath = os.path.dirname(abs_image) + ';' + path for result in py2exe_util.depends(image, loadpath).items(): dll, uses_import_module = result if os.path.basename(dll).lower() not in excluded_dlls: if isSystemDLL(dll): others.add(dll) continue if dll not in images and dll not in dependents: images.add(dll) if uses_import_module: warnings.add(dll) return dependents, warnings, others # DLLs to be excluded # XXX This list is NOT complete (it cannot be) # Note: ALL ENTRIES MUST BE IN LOWER CASE! EXCLUDED_DLLS = ( "advapi32.dll", "comctl32.dll", "comdlg32.dll", "crtdll.dll", "gdi32.dll", "glu32.dll", "opengl32.dll", "imm32.dll", "kernel32.dll", "mfc42.dll", "msvcirt.dll", "msvcrt.dll", "msvcrtd.dll", "ntdll.dll", "odbc32.dll", "ole32.dll", "oleaut32.dll", "rpcrt4.dll", "shell32.dll", "shlwapi.dll", "user32.dll", "version.dll", "winmm.dll", "winspool.drv", "ws2_32.dll", "ws2help.dll", "wsock32.dll", "netapi32.dll", "gdiplus.dll", ) # XXX Perhaps it would be better to assume dlls from the systemdir are system dlls, # and make some exceptions for known dlls, like msvcr71, pythonXY.dll, and so on? def isSystemDLL(pathname): if os.path.basename(pathname).lower() in ("msvcr71.dll", "msvcr71d.dll"): return 0 if os.path.basename(pathname).lower() in EXCLUDED_DLLS: return 1 # How can we determine whether a dll is a 'SYSTEM DLL'? # Is it sufficient to use the Image Load Address? import struct file = open(pathname, "rb") if file.read(2) != "MZ": raise Exception, "Seems not to be an exe-file" file.seek(0x3C) pe_ofs = struct.unpack("i", file.read(4))[0] file.seek(pe_ofs) if file.read(4) != "PE\000\000": raise Exception, ("Seems not to be an exe-file", pathname) file.read(20 + 28) # COFF File Header, offset of ImageBase in Optional Header imagebase = struct.unpack("I", file.read(4))[0] return not (imagebase < 0x70000000) ......分析后可知,错误打印 error: python25.dll: No such file or directory 应该是代码 file = open(pathname, "rb") 产生的,从函数isSystemDLL()的注释可以看出,应该对一些特别版本的dll进行排除,那么可以做如下修改:
if os.path.basename(pathname).lower() in ("msvcr71.dll", "msvcr71d.dll"):改为
if os.path.basename(pathname).lower() in ("msvcr71.dll", "msvcr71d.dll", "python25.dll"):此时执行结果为
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe running py2exe *** searching for required modules *** C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration global START_TIME *** parsing results *** ...... ...... *** finding dlls needed *** Traceback (most recent call last): File "Tribler\Plugin\Build\Win32\setupBGexe.py", line 16, in <module> setup(windows=[mainfile]) File "C:\Python27\lib\distutils\core.py", line 152, in setup dist.run_commands() File "C:\Python27\lib\distutils\dist.py", line 953, in run_commands self.run_command(cmd) File "C:\Python27\lib\distutils\dist.py", line 972, in run_command cmd_obj.run() File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 243, in run self._run() File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 305, in _run dlls = self.find_dlls(extensions) File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 389, in find_dlls self.dll_excludes) File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 1064, in find_dependend_dlls bin_depends(loadpath, images + [sys.executable], excludes_use) File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 1438, in bin_depends for result in py2exe_util.depends(image, loadpath).items(): py2exe_util.bind_error: (2, '', 'python25.dll')呵呵,貌似不行,并且只有py2exe_util.pyd文件,没有源文件,无法进一步知道不行的原因,故换另外一种方法:在EXCLUDED_DLLS增加"python25.dll",执行结果如下
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe running py2exe *** searching for required modules *** C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration global START_TIME *** parsing results *** ...... *** finding dlls needed *** error: MSVCP90.dll: No such file or directory解说说明错误说明找不到 python25.dll的问题已经没有了,但是 需要库MSVCP90.dll。该库是Microsoft C++ Runtime Library,是使用Microsoft Visual Studio 2008编译出的程序默认依赖的库文件。按道理我电脑已经安装了VS2008,该库应该是存在的,但是现在的情况是其确实不在C:\WINDOWS\system32目录下面(和其他系统路径下),故搜索出我电脑上该文件并拷贝到C:\WINDOWS\system32下面,执行程序,终于得到了正确的结果,如下
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe running py2exe *** searching for required modules *** C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration global START_TIME *** parsing results *** ...... *** finding dlls needed *** *** create binaries *** *** byte compile python files *** ...... skipping byte-compilation of ...... skipping byte-compilation of C:\Python27\Tribler\vlc.py to Tribler\vlc.pyc byte-compiling C:\Python27\build\bdist.win32\winexe\temp\M2Crypto.__m2crypto.py to M2Crypto\__m2crypto.pyc byte-compiling ...... ...... skipping byte-compilation of C:\Python27\lib\zipfile.py to zipfile.pyc *** copy extensions *** *** copy dlls *** copying C:\Python27\lib\site-packages\py2exe\run_w.exe -> C:\Python27\dist\SwarmEngine.exe The following modules appear to be missing ['ElementC14N', 'Tribler.Core.BuddyCast.buddycast', '_curses', '_scproxy', 'core.bootstrap', 'core.identifier', 'core.message', 'c ore.node', 'core.ptime', 'core.routing_table', 'meliae', 'netifaces', 'prctl', 'psyco', 'simplejson', 'test_const', 'vlc.lib.vlc', 'win32com.shell'] *** binary dependencies *** Your executable(s) also depend on these dlls which are not included, you may or may not need to distribute them. Make sure you have the license if you distribute any of them, and make sure you don't distribute files belonging to the operating system. ole32.dll - C:\WINDOWS\system32\ole32.dll OLEAUT32.dll - C:\WINDOWS\system32\OLEAUT32.dll USER32.dll - C:\WINDOWS\system32\USER32.dll python25.dll - python25.dll SHELL32.dll - C:\WINDOWS\system32\SHELL32.dll MSWSOCK.dll - C:\WINDOWS\system32\MSWSOCK.dll WINMM.dll - C:\WINDOWS\system32\WINMM.dll WSOCK32.dll - C:\WINDOWS\system32\WSOCK32.dll COMDLG32.dll - C:\WINDOWS\system32\COMDLG32.dll ADVAPI32.dll - C:\WINDOWS\system32\ADVAPI32.dll mfc90.dll - C:\Python27\lib\site-packages\Pythonwin\mfc90.dll msvcrt.dll - C:\WINDOWS\system32\msvcrt.dll WS2_32.dll - C:\WINDOWS\system32\WS2_32.dll WINSPOOL.DRV - C:\WINDOWS\system32\WINSPOOL.DRV GDI32.dll - C:\WINDOWS\system32\GDI32.dll gdiplus.dll - C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\gdiplus.dll VERSION.dll - C:\WINDOWS\system32\VERSION.dll KERNEL32.dll - C:\WINDOWS\system32\KERNEL32.dll COMCTL32.dll - C:\WINDOWS\system32\COMCTL32.dll RPCRT4.dll - C:\WINDOWS\system32\RPCRT4.dll MSVCP90.dll - C:\WINDOWS\system32\MSVCP90.dll此时已经编译出了SwarmEngine.exe位于C:\Python27\dist目录下,但是双击执行时,仍旧不能正常安装,错误日志查看SwarmEngine.exe.log解决,本文不再说明。