Question

This question is kind of lengthy but I try to provide you with the details that I think is necessary to find the answer.

I have a C# WPF solution (.Net 4) consisting of a main project, building a WPF windows app, which depends on a few class library projects residing in the same Visual Studio 2010 solution.

One of the class library projects encapsulates some previously developed python code that I want to make use of through IronPython and Microsoft Dynamic Language Runtime. I would like the class library project to be self contained and not depend on a complete installation of IronPython.

The problem is that I don't know how to refer to the encapsulating library project holding the python code in a way that always work.

Normally I would just add a reference to the class library project as discussed in this question: Visual Studio 2010: How refer to a C# .Net class library project with third part dependencies. However it did not help.

How the solution is set up in Visual Studio:

The solution looks like this:

  • MainApp (windows WPF application project)
    • ...
  • ClassLib1 (C# class library project)
    • ...
  • ClassLibWithPython (C# class library project with IronPython)
    • C# classes
    • lib (directory)
      • IronPython.dll
      • IronPython.Modules.dll
      • Microsoft.Dynamic.dll
      • Microsoft.Scripting.dll
      • Microsoft.Scripting.Metadata.dll
      • pylib (directory with some used python modules)
        • os.py
        • ... .py
      • ctypes (directory with some used python modules)
      • my pyton classes (directory)

ClassLibWithPython has references to the IronPython DLLs residing in its local lib folder (Copy Local attribute True). The MainApp project has references to ClassLib1 project and ClassLibWithPython project (also with Copy Local attribute True).

When compiling the solution all DLLs and the MainApp.exe file shows up in MainApp/bin/Debug and it works fine on some machines (XP and Win 7) however it fails on some other machines (XP). After doing some debugging I've found that the built-in IronPython modules are not loaded correctly. When importing the os module (pylib/os.py like this one http://pydoc.org/get.cgi/usr/local/lib/python2.5/os.py) I get a python exception (ImportError, no os specific module found) due to missing module name 'nt'.

When comparing what's happening where it works and where it doesn't I've found that sys.builtin_module_names just returns a few items compared to what I get when running the same code on some other machines.

Problematic machine has:

sys.builtin_module_names = ['clr', 'future_builtins', 'imp', 'sys', '__builtin__', 'exceptions']

Computers where everything works have:

sys.builtin_module_names: ['clr', 'future_builtins', 'imp', 'sys', '__builtin__', 'exceptions', '_codecs', 'cmath', '_sha512', 'msvcrt', 'array', '_winreg', '_weakref', '_warnings', '_subprocess', '_ssl', '_sre', '_random', '_functools', 'xxsubtype', 'time', 'thread', '_struct', '_heapq', '_ctypes_test', '_ctypes', 'socket', '_sha256', '_sha', 'select', 're', 'operator', 'nt', '_md5', 'math', 'marshal', '_locale', '_io', 'itertools', 'gc', 'errno', 'datetime', 'cStringIO', 'cPickle', 'copy_reg', '_collections', 'binascii', 'zlib', 'signal', 'mmap']

Work-around that didn't help

I've tried to add using statements to the C# code of ClassLibWithPython to make sure even the implicitly referenced assemblies are linked, but with no difference.

Work-arounds that helped

I've found two workarounds providing a working solution, however both of them breaks the encapsulation principle and exposes the implementation details of ClassLibWithPython:

  1. Put all code from ClassLibWithPython in the MainApp project instead.
  2. Keep ClassLibWithPython in a separate project but add references to IronPython.dll and IronPython.Modules.dll to the MainApp project as well.

What is it that make work-around #2 working?

Any suggestions how to make this work in a clean way?

Thank's for reading this far ;-)

Was it helpful?

Solution

I don't fully understand the deployed layout - but try the following.

1) For modules that you expect to be loaded from IronPython.Modules.dll ensure that this assembly is available in your deployment location, and/or hook AssemblyResolve (see here) event if this assembly is in a different location.

2) For modules that you expect to be loaded from a py module. Ensure the probing location is added to sys.path via sys or from the DLR hosting API. eg sys.path.append(...)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top