通过资源在 C# 中嵌入 Python

本文关键字:Python 资源 | 更新日期: 2023-09-27 18:35:19

我已经处理了一个问题一段时间了,我似乎无法解决,所以我需要一些帮助!问题是我正在用 C# 编写一个程序,但我需要一个来自我创建的 Python 文件中的函数。这本身就没有问题:

...Usual Stuff
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting; 
namespace Program
{
    public partial class Form1 : Form
    {
        Microsoft.Scripting.Hosting.ScriptEngine py;
        Microsoft.Scripting.Hosting.ScriptScope s;
        public Form1()
        {
            InitializeComponent();
            py = Python.CreateEngine(); // allow us to run ironpython programs
            s = py.CreateScope(); // you need this to get the variables
        }
        private void doPython()
        {
            //Step 1: 
            //Creating a new script runtime             
            var ironPythonRuntime = Python.CreateRuntime();
            //Step 2:
            //Load the Iron Python file/script into the memory
            //Should be resolve at runtime
             dynamic loadIPython = ironPythonRuntime.;
             //Step 3:
             //Invoke the method and print the result
             double n = loadIPython.add(100, 200);
             numericUpDown1.Value = (decimal)n;
         }
    }
}

但是,这要求文件"first.py"位于程序编译后的任何位置。因此,如果我想共享我的程序,我将不得不同时发送可执行文件和python文件,这非常不方便。我认为解决此问题的一种方法是将"first.py"文件添加到资源并从那里运行......但我不知道该怎么做,甚至不知道是否可能。

当然,上面的代码将不适用于.UseFile 方法采用字符串参数而不是 byte[]。有谁知道我如何进步?

通过资源在 C# 中嵌入 Python

让我们从可能工作的最简单的事情开始,你有一些代码看起来有点像下面:

// ...
py = Python.CreateEngine(); // allow us to run ironpython programs
s = py.CreateScope(); // you need this to get the variables
var ironPythonRuntime = Python.CreateRuntime();
var x = py.CreateScriptSourceFromFile("SomeCode.py");
x.Execute(s);
var myFoo = s.GetVariable("myFoo");
var n = (double)myFoo.add(100, 200);
// ...

我们想用其他东西替换行var x = py.CreateScriptSourceFromFile(...; 如果我们可以将嵌入的资源作为字符串获取,则可以使用 ScriptingEngine.CreateScriptSourceFromString() .

写下这个很好的答案,我们可以得到一些看起来像这样的东西:

string pySrc;
var resourceName = "ConsoleApplication1.SomeCode.py";
using (var stream = System.Reflection.Assembly.GetExecutingAssembly()
                          .GetManifestResourceStream(resourceName))
using (var reader = new System.IO.StreamReader(stream))
{
    pySrc = reader.ReadToEnd();
}
var x = py.CreateScriptSourceFromString(pySrc);