Skip to content Skip to sidebar Skip to footer

Compiling An Ironpython Wpf Project To Exe

What is the best way to pack up an IronPython application for deployment? After scouring the web the best thing I've come up with (and what I'm currently doing) is using clr.Compil

Solution 1:

Use pyc.py to produce app.exe and don't forget to include app.dll and IronPython libraries.

As for XAML - I've created project just for .xaml files that I compile in VS and then use them from IronPython. For example:

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

Solution 2:

It "boils down to IL", but it isn't compatible with the IL that C# code produces, so it can't be directly compiled to a standalone .exe file. You'll need to use pyc.py to compile your code to a stub EXE with the DLL that CompileModules creates. Then distribute those files with IronPython.dll, IronPython.Modules.dll, Microsoft.Dynamic.dll, Microsoft.Scripting.Debugging.dll, Microsoft.Scripting.dll, and of course the XAML file.

To compile other files, just add them as arguments: ipy.exe pyc.py /main:app.py /target:winexe another.py another2.py additional.py

Solution 3:

I posted a Python script which can take an IronPython file, figure out its dependencies and compile the lot into a standalone binary at Ironpython 2.6 .py -> .exe. Hope you find it useful. It ought to work for WPF too as it bundles WPF support.

Solution 4:

To create a set of assemblies for your IronPython application so that you can distribute it you can either use pyc.py or SharpDevelop.

To compile using pyc.py:

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

Given the amount of files in your project you could try using SharpDevelop instead of maintaining a long command line for pyc.py. You will need to create a new IronPython project in SharpDevelop and import your files into the project. You will probably need to import the files one at a time since SharpDevelop lacks a way to import multiple files unless they are in a subfolder.

You can then use SharpDevelop to compile your application into an executable and a dll. All the other required files, such as IronPython.dll, Microsoft.Scripting.dll, will be in the bin/debug or bin/release folder. SharpDevelop uses clr.CompileModules and a custom MSBuild task behind the scenes to generate the binaries.

Any IronPython packages defined in your project should be usable from your application after compilation.

Packaging up the XAML can be done by embedding the xaml as a resource. Then using code similar to the following:

import clr

clr.AddReference('PresentationFramework')
clr.AddReference('System')

fromSystem.IOimportFileMode, FileStream, PathfromSystem.ReflectionimportAssemblyfromSystem.WindowsimportApplicationfromSystem.Windows.MarkupimportXamlReader

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 does not embed resource files correctly so you will need to use SharpDevelop 4.

If you are using IronPython 2.7 you can use the new clr.LoadComponent method that takes an object and either a XAML filename or stream and wires up that object to the XAML.

Whilst the C# compiler can compile your XAML into a BAML resource doing the same with IronPython has a few problems. If you do not link the XAML to a class via the x:Class attribute then it is possible to compile the XAML into a BAML resource and have that embedded into your assembly. However you will not get any autogenerated code so you will need to create that code yourself. Another problem is that this will not work out of the box with SharpDevelop. You will need to edit the SharpDevelop.Build.Python.targets file and change the from Python to C#. Trying to use the x:Class attribute will not work since the BAML reader cannot access any associated IronPython class. This is because the generated IL in the compiled IronPython application is very different to that in a C# or VB.NET assembly.

Solution 5:

I installed Visual Studio 2015 with PTVS (ironpython 2.7). I created a very simple WPF project and wasn't able to compile an exe. I always got the exception "ImportError: No module named 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

classMyWindow(Window):
    def__init__(self):
        wpf.LoadComponent(self, 'RegExTester.xaml')

    defOnSearch(self, sender, e):
        self.tbOut.Text = "hello world"if __name__ == '__main__':
    Application().Run(MyWindow())

The fault I got was because the clr clause must be before the import wpf. Steps to compile it:

  1. install pip for CPython 2.7 (not ironpython!)

  2. install ipy2asm

python -m pip install ironpycompiler

  1. compile the application like

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

Post a Comment for "Compiling An Ironpython Wpf Project To Exe"