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:
- Put all code from ClassLibWithPython in the MainApp project instead.
- 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 ;-)