Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IronPython Excel-Dna Add-In - Exception regarding Microsoft.Dynamic reference

I am getting started with developing an Excel-DNA addin using IronPython with some C# as a wrapper for the calls to IronPython. With the generous help of the Excel-DNA developer, I have worked through some of the initial kinks of getting a sample up and running, but now I am trying to debug the addin in SharpDevelop, and I'm running into some problems. As I'm completely new to most of this, I'm not really sure if it is an issue with SharpDevelop, .NET, Excel-DNA or IronPython.

I have created two projects in one solution, one is a C# class library. The other is a python class library. I setup the project to debug following a tutorial I found on a blog. I am able to step through the first few lines of C# code, so that is progress, but when I get to the following line:

pyEngine.Runtime.LoadAssembly(myclass); 

I get an exception:

"Could not load file or assembly 'Microsoft.Dynamic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)"

But I'm pretty sure I have added the Microsoft.Dynamic reference to my project. It is version 1.1.0.20. This is included in the IronPython distribution but also in another location on my computer. I have tried setting the reference to both, but they both have the same version number and appear to be the same file size. Neither one works. Do I need version 1.0.0.0 or am I doing something else wrong? I don't really understand why anything pyEngine (the ScriptEngine returned by Python.CreateEngine()) would try to load a different version than the one included with the distribution.

Code is below. Let me know if you need any other information.

MyAddin.cs

/*
Added these references all as Local Copies - probably not necessary?

System.Windows.Forms
Microsoft.CSharp

ExcelDna.Integration (from Excel-DNA distribution folder)
IronPython (from IronPython folder)
IronPython.Modules (from IronPython folder)
Microsoft.Dynamic (from IronPython folder)
Microsoft.Scripting (from IronPython folder)
Microsoft.Scripting.Metadata (from IronPython folder)

mscorlib (I don't really know why I added this, but it was one of the references in my IronPython class library)

MyClass (this is the reference to my IronPython class - I checked to see that it gets copied in every time I rebuild the solution and it does)

These were automatically added by SharpDevelop when I created the project.
System
System.Core
System.Windows.Forms
System.Xml
System.Xml.Linq
*/
using System;
using System.IO;
using System.Windows.Forms;
using ExcelDna.Integration;
using System.Reflection;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

public class MyAddIn : IExcelAddIn
{
    public void AutoOpen()
    {
        try
        {
            string xllDirectory  = Path.GetDirectoryName(@"C:/Users/myname/Documents/SharpDevelop Projects/IronPythonExcelDNATest/MyAddIn/bin/Debug/");
            string dllPath = Path.Combine(xllDirectory,"MyClass.dll");
            Assembly myclass = Assembly.LoadFile(dllPath);
            ScriptEngine pyEngine = Python.CreateEngine();
            pyEngine.Runtime.LoadAssembly(myclass);
            ScriptScope pyScope = pyEngine.Runtime.ImportModule("MyClass");
            object myClass = pyEngine.Operations.Invoke(pyScope.GetVariable("MyClass"));
            IronTest.AddSomeStuff = pyEngine.Operations.GetMember<Func<double, double,double>>(myClass, "AddSomeStuff");
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }
    public void AutoClose()
    {
    }
}

public class IronTest
{
    public static Func<double, double, double> AddSomeStuff;
    public static double TestIPAdd(double val1, double val2)
    {
        try
        {
            return AddSomeStuff(val1, val2);
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
            return double.NaN;
        }
    }
}

MyClass.py

class MyClass:
    def __init__(self):
        pass

    def AddSomeStuff(self,x,y):
        return x + y
like image 973
oob Avatar asked Oct 24 '22 17:10

oob


1 Answers

Your IronPython stuff probably needs to run under the .NET 4 runtime. To tell Excel-DNA to load .NET 4, you have to explicitly add a RuntimeVersion attribute in the main .dna file. Your .dna file will start with something like:

<DnaLibrary RuntimeVersion="v4.0"> ... </DnaLibrary>

The default behaviour, if the attribute is omitted, is to load the .NET 2.0 version of the runtime (which is also used by .NET 3.0 and 3.5).

It might be possible to host IronPython under the .NET 2.0 runtime, but then you need to deal with the DLR libraries yourself, whereas they are built-in and already installed with .NET 4.

like image 158
Govert Avatar answered Oct 27 '22 09:10

Govert