2014-02-02 3 views
0

Этот простой код работает очень хорошо:wx.ProgressDialog + py2exe приводит к применению аварии

import wx 
app = wx.App(0) 
frame = wx.Frame(None) 
test = wx.ProgressDialog('Test', 'Test', maximum = 20, parent = frame, style = wx.PD_CAN_ABORT) 
app.MainLoop() 

Однако, при компиляции/упаковки его в исполняемый файл с py2exe ...

from distutils.core import setup 
import py2exe 
setup(script_args = ['py2exe'], windows=[{'script':'progressdlgprobblem.py'}], 
    options = {'py2exe': {'compressed':1,'bundle_files': 1}}, zipfile = None) 

.. , затем сбой файла .exe.

Что может быть причиной этой аварии? Требуется ли wx.ProgressDialog некоторые дополнительные дополнительные элементы для использования с py2exe?


Добавление 1: когда я удалить style = wx.PD_CAN_ABORT, там больше нет аварии. Как может произойти сбой с style? Но тогда, то стиль является XP стиль при запуске из .exe:

enter image description here

и отличается от стиля я получаю при запуске из .py (без py2exe):

enter image description here


Addendum 2: whe n Я удаляю 'bundle_files': 1, больше нет сбоев. Но я хотел бы сохранить это связывание только в одном файле! Как это объединение в один .exe-файл станет причиной этого сбоя?

Добавление 3: Большая часть проблемы решается с помощью wx.Python 3.0.1.0b вместо 3.0.0.0 (более подробно в ближайшее время).

+0

Любые детали аварии? – hivert

+0

Стандартное диалоговое окно «test.exe перестало работать», без какого-либо сообщения журнала – Basj

+0

Попробуйте сделать ярлык для полученного exe с помощью 'C: \ Windows \ system32 \ cmd.exe/K" path-to-your-exe "' в Целевом. С удачей окно команд останется открытым, показывая вам трассировку ... – GreenAsJade

ответ

1

Имел проблемы с примером ProgressDialog и добавил прогресс и очистку, но в остальном не изменился.

# -*- coding: utf-8 -*- 
import wx 
app = wx.App(0) 
frame = wx.Frame(None) 
max_count = 8 
dlg = wx.ProgressDialog('Test caption', 'Test text', maximum = max_count, parent = frame, style = wx.PD_CAN_ABORT) 

keepGoing = True # progress routine from wxPython demo 
count = 0 

while keepGoing and count < max_count: 
    count += 1 
    wx.MilliSleep(125) 
    wx.Yield() 
    (keepGoing, skip) = dlg.Update(count, 'progress: {0} %'.format(count * 100.0/max_count))   

dlg.Destroy() # proper cleanup otherwise process has to be killed 
frame.Destroy() 

app.MainLoop() 

py2exe Замерзаем является боль в заднице, но доставляет ИМХО все-таки хороший результат для платформы Windows. Значительная часть настроек - это попытка и ошибка. В wxPython wiki есть хорошее описание/объяснение того, как управлять сборкой SxS и манифестом.

# -*- coding: utf-8 -*- 
"""manifest fixes NT-theming and including MSVC runtime issue""" 

""" 
# Recipe from 
http://wiki.wxpython.org/Py2exe%20with%20Python2.6 
""" 

manifest = """ 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity 
    version="5.0.0.0" 
    processorArchitecture="x86" 
    name="%(prog)s" 
    type="win32" 
    /> 
    <description>%(prog)s</description> 
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
    <security> 
     <requestedPrivileges> 
     <requestedExecutionLevel 
      level="asInvoker" 
      uiAccess="false"> 
     </requestedExecutionLevel> 
     </requestedPrivileges> 
    </security> 
    </trustInfo> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
      type="win32" 
      name="Microsoft.VC90.CRT" 
      version="9.0.21022.8" 
      processorArchitecture="x86" 
      publicKeyToken="1fc8b3b9a1e18e3b"> 
     </assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
      type="win32" 
      name="Microsoft.Windows.Common-Controls" 
      version="6.0.0.0" 
      processorArchitecture="X86" 
      publicKeyToken="6595b64144ccf1df" 
      language="*" 
     /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 
""" 

from distutils.core import setup 
import py2exe 
dll_excludes = [ 
    'w9xpopen.exe', 
    'MSVCP90.dll' # reason see link to wxPython-wiki above 
] 
setup(script_args = ['py2exe'], windows=[{'script':'progressdlg.py',# 
              "other_resources": [(24, 1, manifest)]}], # manifest added 
    options = {'py2exe': {'compressed':1,'bundle_files': 1, 'dll_excludes': dll_excludes, 
         }}, zipfile = None) 

По крайней мере, на моей машине (WinXP 7 + WxPython 2.9.5.0) эта установка (python setup.py py2exe) производит:

  • Один .EXE
  • Правильная тематизации также при замороженном
  • Нет аварий , полное удобство использования, используйте флаги стиля, которые вам нравятся

Пример: l восток на вашем компьютере (где уже установлены MSCV).Для более полного списка исключений см. Параллельный поток в [wxPython-users] https://groups.google.com/forum/#!topic/wxpython-users/vrd-0cpiH1E.

В библиотеке esky есть исправления для уже включенных приколов и предлагается обновление в реальном времени для wx -Apps, но вам может понравиться или не понравиться структура проекта, которую он настраивает.

Боковое примечание: я не смог воспроизвести ваш сбой на wxPython 2.9.5.0 (даже без сборки). У меня были сбои в XP при замораживании с 3.0.0.0 на машине Win8, но это должно быть разрешено в 3.0.1 в соответствии с Robin (см. https://groups.google.com/forum/#!topic/wxpython-users/8OeBfxTC9Xo).

Боковое примечание 2: Кажется, это проблема с wxPython 3.0.0.0 (classic). На моей машине XP эти примеры вылетают, даже если они не заморожены. Если обновление до wxPython 3.0.1 (phoenix), то оно снова работает (как размороженное, так и py2exe'd). Замороженный одиночный файл EXE работает без проблем в Windows8, 64 бит и WinXP с правильной темой.

+0

Я точно выполнил ваши шаги (на Win7 x64 + (Anaconda) Python 2.7 x86 + wxPython 3.0.0.0) и .. крушение! :(Я все еще даю вам щедрость и спасибо за потраченное время! Ну, теперь сдайтесь с 'bundle_files: 1' и фактом наличия одного' .exe' ... – Basj

+0

Я надеялся вырвать «Принимается», но это невозможно в вашем вопросе. WxPython 3.0.0.0, по-видимому, нарушен в этом отношении (см. Примечание к стороне 2). – nepix32

+0

Bounty намного лучше, чем Принято здесь;) Да, возможно, это будет разрешено в следующая версия ... Или, может быть, эта проблема полностью исчезнет, ​​если я отформатирую свой жесткий диск и переустановить все модули Python + на моем компьютере в один прекрасный день ... На данный момент я отключил 'bundle_files = 1'. – Basj

2

py2exe (0.6.9) довольно устарел и не справляется с новыми версиями Windows, без каких-либо дополнительных изменений. В частности, он будет по умолчанию включать некоторые системные DLL-системы Windows, которые никогда не должны быть связаны. Чтобы избежать этого, попробуйте изменить сценарий установки следующим образом:

from distutils.core import setup 
import py2exe 

# Exclude system DLLs 
origIsSystemDLL = py2exe.build_exe.isSystemDLL 
def isSystemDLL(pathname): 
    if os.path.basename(pathname).lower() in ("gdiplus.dll", 
               "mfc90.dll"): 
     return 0 
    if os.path.basename(pathname).lower() in ("powrprof.dll",) or \ 
     os.path.basename(pathname).lower().startswith("api-ms-win-"): 
     return 1 
    return origIsSystemDLL(pathname) 
py2exe.build_exe.isSystemDLL = isSystemDLL 

# Add the MS VC9 CRT and common controls manifest as resource to the exe 
manifest = '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity 
    version="0.0.0.0" 
    processorArchitecture="x86" 
    name="Enter program name here" 
    type="win32" 
    /> 
    <description>Enter program description here</description> 
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
    <security> 
     <requestedPrivileges> 
     <requestedExecutionLevel level="asInvoker" uiAccess="false" /> 
     </requestedPrivileges> 
    </security> 
    </trustInfo> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
     type="win32" 
     name="Microsoft.Windows.Common-Controls" 
     version="6.0.0.0" 
     processorArchitecture="x86" 
     publicKeyToken="6595b64144ccf1df" 
     language="*" 
     /> 
    </dependentAssembly> 
    </dependency> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity 
     type="win32" 
     name="Microsoft.VC90.CRT" 
     version="9.0.21022.8" 
     processorArchitecture="x86" 
     publicKeyToken="1fc8b3b9a1e18e3b" 
     /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 
''' 

setup(script_args=['py2exe'], 
     windows=[{'script': 'progressdlgprobblem.py', 
       'other_resources': [(24, 1, manifest)]}], 
     options = {'py2exe': {'compressed': 1, 
          'dll_excludes': ['iertutil.dll', 
              'MPR.dll', 
              'msvcm90.dll', 
              'msvcp90.dll', 
              'msvcr90.dll', 
              'mswsock.dll', 
              'urlmon.dll', 
              'w9xpopen.exe'], 
          'bundle_files': 1}}, 
     zipfile=None) 

Для лучшей совместимости, вы также хотите скопировать Microsoft.VC90.CRT.manifest, msvcm90.dll, msvcp90.dll и msvcr90.dll от C: \ Windows \ winsxs \ x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_none_bcb86ed6ac711f91 (имя каталога может немного отличаться, но правильная версия 9.0.21022.8 важна) в каталог вашего exe, так что пользователям не нужно устанавливать права версии самого MS VC9 CRT.

В качестве альтернативы, вы можете попробовать PyInstaller, который автоматически обрабатывает зависимости сборки и исключает системные DLL по умолчанию.

Смежные вопросы