¿Cuál es la mejor manera de empaquetar una aplicación IronPython para su implementación? Después de recorrer la Web, lo mejor que he encontrado (y lo que estoy haciendo actualmente) es usar clr.CompileModules()
para unir todos los archivos .py de todo el proyecto en un .dll, y luego tener un solo run.py
hacer esto para ejecutar el DLL:Compilación de un proyecto IronPython WPF a exe
import clr
clr.AddReference('compiledapp.dll')
import app
Esto sigue siendo subóptima, sin embargo, porque significa que tengo que
- distribuir 3 archivos (el
.dll
, la.xaml
, y elrun.py
lanzador) - Instalar IronPython en el máquina host
Además, esto se siente tan ... hacky, después de la maravillosa integración IronPython ya con Visual Studio 2010. Estoy completamente desconcertado por qué no hay un sistema de construcción integrado para aplicaciones API, ya que todo se reduce a IL de todos modos.
Idealmente, quiero ser capaz de tener una sola .exe
con el .xaml
fusionaron en el interior de alguna manera (leí que C# aplicaciones compilan XAML a BAML y se funden en el ejecutable), y sin necesidad de IronPython para ser instalado para funcionar. ¿Es esto al menos a medio camino posible? (Supongo que está bien si el exe necesita algunas .DLLs adicionales con ella o algo La parte importante es que es en .exe formulario..)
Algunas modificaciones para aclarar: He tratado pyc. py, pero parece no reconocer el hecho de que mi proyecto no es solo app.py
. El tamaño del exe que produce sugiere que simplemente 'compila' app.py
sin incluir ninguno de los otros archivos en el exe. Entonces, ¿cómo le digo que compile todos los archivos de mi proyecto?
To help visualize this, here is a screenshot of my project's solution explorer window.
Editar II: Parece que, lamentablemente, la única manera es utilizar pyc.py
y pasar cada archivo a ella como un parámetro. Hay dos preguntas que tengo para este enfoque:
- ¿Cómo puedo procesar una línea de comando tan grande? Hay un máximo de 256 caracteres en un comando.
- ¿Cómo sabe pyc.py preservar la estructura del paquete/carpeta? Como se muestra en la captura de pantalla de mi proyecto anterior, ¿cómo sabrá mi programa compilado acceder a los módulos que están en subcarpetas, como el acceso a DT \ Dispositivo? Es la jerarquía de alguna manera "conservada" en el dll?
Editar III: Desde 70 nombres de archivo que pasa a través de pyc.py
la línea de comandos será difícil de manejar, y con el fin de resolver el problema de la construcción de los proyectos del API más elegante, he decidido aumentar pyc.py
.
He agregado el código que se lee en un archivo .pyproj
a través del parámetro /pyproj:
, analiza el XML y toma de allí la lista de archivos py utilizados en el proyecto. Esto ha estado funcionando bastante bien; sin embargo, parece que el ejecutable producido no puede acceder a los subpaquetes de python (subcarpetas) que forman parte de mi proyecto. Mi versión de pyc.py
con mi parche de apoyo .pyproj
lectura se puede encontrar aquí: http://pastebin.com/FgXbZY29
Cuando esta nueva pyc.py
se ejecuta en mi proyecto, esta es la salida:
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 tanto, leer 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
Así que, aunque Cu64\ui.py
es, obviamente, incluido en la compilación, el exe, cuando se ejecuta, no puede encontrarlo. Esto es a lo que le tenía miedo en el punto n. ° 2 de la edición anterior. ¿Cómo conservo la jerarquía de paquetes de mi proyecto? ¿Quizás compilar cada paquete por separado puede ser necesario?
Extenderé la recompensa por esta pregunta. En última instancia, mi esperanza es que podamos obtener un pyc.py que funcione y que se lea en archivos pyproj y produzca archivos en un solo paso. Entonces tal vez incluso podría enviarse al codeplex de IronPython para ser incluido en la próxima versión ...;]
La longitud de la línea de comando es de 8191 caracteres (http://support.microsoft.com/kb/830473). 'clr.CompileModules' maneja bien los paquetes - los reconoce a través de' __init __. py' como es usual para los paquetes de Python. –
Sí, puede usar clr.CompileModules y luego crear un stub .exe que cargue el .dll. Creo que hay una función LoadAssembly en algún lugar que se puede usar en C#. – jcao219
Ah, quise decir que 'pyc.py' usa' clr.CompileModules', que maneja bien los paquetes.Así que solo use pyc.py y debería funcionar ;-) –