c # - Opret et python COM objekt

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg spekulerer på, om der er nogen måde at indkapslere et python-script som et COM-objekt.


Jeg har set, at mange emner snakker om at påberåbe sig en COM-komponent fra python, men jeg er interesseret i det modsatte: at oprette en COM-komponent, der faktisk er python.


Jeg har nogle biblioteker lavet i python, at jeg vil blive kaldt fra et Excel-regneark, og jeg synes, det kunne være en god måde at gøre dette på.

Bedste reference


En måde at måske gøre dette på er at skabe et COM-objekt ved hjælp af .NET og udføre Python-kode ved hjælp af IronPython.


Her er en ide om, hvordan det kunne fungere:


using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using IronPython.Hosting;

namespace PythonComObject
{
    [Guid("F34B2821-14FB-1345-356D-DD1456789BBF")]
    public interface PythonComInterface
    {
        [DispId(1)]
        bool RunSomePython();
        [DispId(2)]
        bool RunPythonScript();
    }

    // Events interface 
    [Guid("414d59b28-c6b6-4e65-b213-b3e6982e698f"), 
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface PythonComEvents 
    {
    }

    [Guid("25a337e0-161c-437d-a441-8af096add44f"),
    ClassInterface(ClassInterfaceType.None),
    ComSourceInterfaces(typeof(PythonComEvents))]
    public class PythonCom : PythonComInterface
    {
        private ScriptEngine \_engine;

        public PythonCom()
        {
            // Initialize IronPython engine
            \_engine = Python.CreateEngine();
        }

        public bool RunSomePython()
        {
            string someScript = @"def return\_message(some\_parameter):
                                      return True";
            ScriptSource source = \_engine.CreateScriptSourceFromString(someScript, SourceCodeKind.Statements);

            ScriptScope scope = \_engine.CreateScope();
            source.Execute(scope);
            Func<int, bool> ReturnMessage = scope.GetVariable<Func<int, bool>>("return\_Message");

            return ReturnMessage(0);
        }


        public bool RunPythonScript()
        {
            ScriptSource source = \_engine.CreateScriptSourceFromFile("SomeScript.py");
            ScriptScope scope = \_engine.CreateScope();
            source.Execute(scope);               
            Func<int, bool> some\_method = scope.GetVariable<Func<int, bool>>("some\_method");
            return some\_method(1);
        }
    }
}


Jeg har ikke prøvet dette, det er bare en ide, jeg håber det virker eller i det mindste får dig i den rigtige retning.


Nogle nyttige referencer:


https://blogs.msdn.microsoft.com/seshadripv/2008/06/30/how-to-invoke-a-ironpython-function-from-c-using-the-dlr-hosting-api/[2]]]


http://ironpython.net [3]


https://www.nuget.org/packages/IronPython/[4]