visual tutorial tools studio net for python wpf visual-studio-2010 ironpython

tutorial - Compilando un proyecto WPF de IronPython a exe



ironpython tutorial (5)

¿Cuál es la mejor manera de empaquetar una aplicación IronPython para la implementación? Después de explorar la web, lo mejor que he encontrado (y lo que estoy haciendo actualmente) es usar clr.CompileModules() para pegar todos los archivos .py de mi proyecto en una sola .dll, y luego tener una sola run.py hacer esto para ejecutar el dll:

import clr clr.AddReference(''compiledapp.dll'') import app

Esto sigue siendo subóptimo, sin embargo, porque significa que tengo que

  1. distribuye 3 archivos (el .dll , el .xaml y el lanzador run.py )
  2. instala IronPython en la máquina host

Además, esto se siente tan ... hacky, después de la maravillosa integración que IronPython ya tiene con Visual Studio 2010. Estoy completamente desconcertado de por qué no hay un sistema de compilación integrado para las aplicaciones IPy, ya que todo se reduce a IL de todos modos.

Idealmente, quiero poder tener un único .exe con el .xaml combinado de alguna manera (leí que las aplicaciones de C # compilan XAML en BAML y las combinan en el ejecutable), y sin requerir que IronPython esté instalado para ejecutarse. ¿Es esto al menos la mitad posible? (Supongo que está bien si el exe necesita algunos .DLL adicionales con eso o algo así. Lo importante es que está en formato .exe).

Algunas ediciones para aclarar: he probado pyc.py , pero parece no reconocer el hecho de que mi proyecto no es solo app.py El tamaño del app.py que produce sugiere que solo está ''compilando'' app.py sin incluir ninguno de los otros archivos en el archivo ejecutable. Entonces, ¿cómo le digo a compilar cada archivo en mi proyecto?

Para ayudar a visualizar esto, aquí hay una captura de pantalla de la ventana del explorador de soluciones de mi proyecto.

Edición II: Parece que, desafortunadamente, la única forma es usar pyc.py y pasarle cada archivo como parámetro. Hay dos preguntas que tengo para este enfoque:

  1. ¿Cómo puedo procesar una línea de comando tan grande? Hay un máximo de 256 caracteres en un comando.
  2. ¿Cómo sabe pyc.py para preservar la estructura del paquete / carpeta? Como se muestra en la captura de pantalla de mi proyecto anterior, ¿cómo sabrá mi programa compilado para acceder a los módulos que se encuentran en las subcarpetas, como el acceso a DT / Device? ¿Está la jerarquía de alguna manera ''preservada'' en la dll?

Edición III : Desde que pasar 70 nombres de archivos a pyc.py través de la línea de comandos será difícil de manejar, y con el interés de resolver el problema de crear proyectos IPy con más elegancia, he decidido aumentar pyc.py

He agregado código que se lee en un archivo .pyproj través del parámetro /pyproj: analiza el XML y toma de allí la lista de archivos py que se usa en el proyecto. Esto ha estado funcionando bastante bien; sin embargo, el ejecutable producido parece no poder acceder a los subpaquetes de Python (subcarpetas) que forman parte de mi proyecto. Mi versión de pyc.py con mi parche de soporte de lectura .pyproj se puede encontrar aquí: http://pastebin.com/FgXbZY29

Cuando este nuevo pyc.py se ejecuta en mi proyecto, este es el resultado:

c:/Projects/GenScheme/GenScheme>"c:/Program Files (x86)/IronPython 2.7/ipy.exe" pyc.py /pyproj:GenScheme.pyproj /out:App /main:app.py /target:exe Input Files: c:/Projects/GenScheme/GenScheme/__init__.py c:/Projects/GenScheme/GenScheme/Agent.py c:/Projects/GenScheme/GenScheme/AIDisplay.py c:/Projects/GenScheme/GenScheme/app.py c:/Projects/GenScheme/GenScheme/BaseDevice.py c:/Projects/GenScheme/GenScheme/BaseManager.py c:/Projects/GenScheme/GenScheme/BaseSubSystem.py c:/Projects/GenScheme/GenScheme/ControlSchemes.py c:/Projects/GenScheme/GenScheme/Cu64/__init__.py c:/Projects/GenScheme/GenScheme/Cu64/agent.py c:/Projects/GenScheme/GenScheme/Cu64/aidisplays.py c:/Projects/GenScheme/GenScheme/Cu64/devmapper.py c:/Projects/GenScheme/GenScheme/Cu64/timedprocess.py c:/Projects/GenScheme/GenScheme/Cu64/ui.py c:/Projects/GenScheme/GenScheme/decorators.py c:/Projects/GenScheme/GenScheme/DeviceMapper.py c:/Projects/GenScheme/GenScheme/DT/__init__.py c:/Projects/GenScheme/GenScheme/DT/Device.py c:/Projects/GenScheme/GenScheme/DT/Manager.py c:/Projects/GenScheme/GenScheme/DT/SubSystem.py c:/Projects/GenScheme/GenScheme/excepts.py c:/Projects/GenScheme/GenScheme/FindName.py c:/Projects/GenScheme/GenScheme/GenScheme.py c:/Projects/GenScheme/GenScheme/PMX/__init__.py c:/Projects/GenScheme/GenScheme/PMX/Device.py c:/Projects/GenScheme/GenScheme/PMX/Manager.py c:/Projects/GenScheme/GenScheme/PMX/SubSystem.py c:/Projects/GenScheme/GenScheme/pyevent.py c:/Projects/GenScheme/GenScheme/Scheme.py c:/Projects/GenScheme/GenScheme/Simulated/__init__.py c:/Projects/GenScheme/GenScheme/Simulated/Device.py c:/Projects/GenScheme/GenScheme/Simulated/SubSystem.py c:/Projects/GenScheme/GenScheme/speech.py c:/Projects/GenScheme/GenScheme/stdoutWriter.py c:/Projects/GenScheme/GenScheme/Step.py c:/Projects/GenScheme/GenScheme/TimedProcess.py c:/Projects/GenScheme/GenScheme/UI.py c:/Projects/GenScheme/GenScheme/VirtualSubSystem.py c:/Projects/GenScheme/GenScheme/Waddle.py Output: App Target: ConsoleApplication Platform: ILOnly Machine: I386 Compiling... Saved to App

Por lo que se lee correctamente en la lista de archivos en el .pyproj ... ¡Genial! Pero correr el exe me da esto:

Unhandled Exception: IronPython.Runtime.Exceptions.ImportException: No module named Cu64.ui

Entonces, aunque Cu64/ui.py está obviamente incluido en la compilación, el ejecutable, cuando se ejecuta, no puede encontrarlo. Esto es lo que temía en el punto # 2 en la edición anterior. ¿Cómo conservo la jerarquía de paquetes de mi proyecto? Tal vez compilar cada paquete por separado puede ser necesario?

Voy a extender la recompensa por esta pregunta. En última instancia, mi esperanza es que podamos obtener un pyc.py de trabajo que se lea en archivos pyproj y produzca exes de trabajo en un solo paso. Entonces, tal vez podría incluso enviarse al código de IronPython para incluirlo en la próxima versión ...;]


Instalé Visual Studio 2015 con PTVS (ironpython 2.7). Creé un proyecto WPF muy simple y no pude compilar un exe. Siempre obtuve la excepción "ImportError: No hay módulo llamado wpf".

import clr clr.AddReferenceToFileAndPath("c://path//to//IronPython.Wpf.dll") clr.AddReferenceToFileAndPath(''c://path//to//PresentationCore.dll'') clr.AddReferenceToFileAndPath(''c://path//to//PresentationFramework.dll'') clr.AddReferenceToFileAndPath(''c://path//to//WindowsBase.dll'') from System.Windows import Application, Window import wpf class MyWindow(Window): def __init__(self): wpf.LoadComponent(self, ''RegExTester.xaml'') def OnSearch(self, sender, e): self.tbOut.Text = "hello world" if __name__ == ''__main__'': Application().Run(MyWindow())

El error que obtuve fue porque la cláusula clr debe estar antes de la importación wpf. Pasos para compilarlo:

  1. instale pip para CPython 2.7 (no ironpython!)

  2. instalar ipy2asm

python -m pip instala ironpycompiler

  1. compilar la aplicación como

ipy2asm compile -t winexe -e -s program.py


Para crear un conjunto de ensamblajes para su aplicación IronPython para que pueda distribuirlo, puede usar pyc.py o SharpDevelop.

Para compilar usando pyc.py:

ipy.exe pyc.py /main:Program.py Form.py File1.py File2.py ... / target: winexe

Dada la cantidad de archivos en su proyecto, podría intentar usar SharpDevelop en lugar de mantener una larga línea de comandos para pyc.py. Necesitará crear un nuevo proyecto IronPython en SharpDevelop e importar sus archivos al proyecto. Es probable que deba importar los archivos uno por uno, ya que SharpDevelop carece de una forma de importar varios archivos a menos que estén en una subcarpeta.

Luego puede usar SharpDevelop para compilar su aplicación en un ejecutable y un archivo DLL. Todos los demás archivos necesarios, como IronPython.dll, Microsoft.Scripting.dll, estarán en la carpeta bin / debug o bin / release. SharpDevelop usa clr.CompileModules y una tarea personalizada de MSBuild detrás de la escena para generar los binarios.

Cualquier paquete de IronPython definido en su proyecto debe poder utilizarse desde su aplicación después de la compilación.

El empaquetado de la XAML se puede hacer incrustando el xaml como un recurso. Luego usando código similar al siguiente:

import clr clr.AddReference(''PresentationFramework'') clr.AddReference(''System'') from System.IO import FileMode, FileStream, Path from System.Reflection import Assembly from System.Windows import Application from System.Windows.Markup import XamlReader executingAssemblyFileName = Assembly.GetEntryAssembly().Location directory = Path.GetDirectoryName(executingAssemblyFileName) xamlFileName = Path.Combine(directory, "Window1.xaml") stream = FileStream(xamlFileName, FileMode.Open) window = XamlReader.Load(stream) app = Application() app.Run(window)

SharpDevelop 3.2 no incrusta archivos de recursos correctamente, por lo que necesitará usar SharpDevelop 4.

Si está usando IronPython 2.7, puede usar el nuevo método clr.LoadComponent que toma un objeto y un nombre de archivo o flujo de XAML y conecta ese objeto a la XAML.

Mientras que el compilador de C # puede compilar su XAML en un recurso BAML, hacer lo mismo con IronPython tiene algunos problemas. Si no vincula el XAML a una clase a través del atributo x: Class, es posible compilar el XAML en un recurso BAML y tenerlo incorporado en su ensamblaje. Sin embargo, no obtendrá ningún código generado automáticamente, por lo que tendrá que crearlo usted mismo. Otro problema es que esto no funcionará directamente con SharpDevelop. Necesitará editar el archivo SharpDevelop.Build.Python.targets y cambiar el de Python a C #. Tratar de usar el atributo x: Class no funcionará ya que el lector BAML no puede acceder a ninguna clase asociada de IronPython. Esto se debe a que la IL generada en la aplicación IronPython compilada es muy diferente a la de un ensamblaje C # o VB.NET.


Publiqué un script en Python que puede tomar un archivo de IronPython, averiguar sus dependencias y compilar el lote en un binario independiente en Ironpython 2.6 .py -> .exe . Esperamos que te sea útil. También debería funcionar para WPF, ya que agrupa el soporte de WPF.


Se "reduce a IL", pero no es compatible con la IL que produce el código C #, por lo que no se puede compilar directamente en un archivo .exe independiente. Necesitará usar pyc.py para compilar su código en un código auxiliar EXE con la DLL que crea CompileModules. Luego distribuya esos archivos con IronPython.dll , IronPython.Modules.dll , Microsoft.Dynamic.dll , Microsoft.Scripting.Debugging.dll , Microsoft.Scripting.dll y, por supuesto, el archivo XAML.

Para compilar otros archivos, simplemente agréguelos como argumentos: ipy.exe pyc.py /main:app.py /target:winexe another.py another2.py additional.py


Use pyc.py para producir app.exe y no olvide incluir las bibliotecas app.dll y IronPython.

En cuanto a XAML, he creado proyectos solo para archivos .xaml que compilo en VS y luego los uso desde IronPython. Por ejemplo:

<ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/CompiledStyle;component/Style.xaml" /> </ResourceDictionary.MergedDictionaries>