如何正确设置 IronPython 的 CodeContext 以直接从 C# 调用 IO?

How to properly setup CodeContext of IronPython to directly invoke IO from C#?

我正在尝试从 C# 直接调用 IronPython 的内置模块。看起来我缺少一些重要的初始化,我在代码中找不到任何地方。

这是我的做法:

namespace py.consoleio
{
    using IronPython.Runtime;
    using Microsoft.Scripting.Hosting;
    using Microsoft.Scripting.Hosting.Providers;
    using Microsoft.Scripting.Runtime;

    public static class consoleio
    {
        public static string name;

        static void Main()
        {
            var setup = new ScriptRuntimeSetup();
            setup.LanguageSetups.Add(
                IronPython.Hosting.Python.CreateLanguageSetup(null));
            var dlrRuntime = new ScriptRuntime(setup);
            var scriptDomainManager = HostingHelpers.GetDomainManager(dlrRuntime);
            var pythonContext = new PythonContext(scriptDomainManager, null);
            var context = new CodeContext(new PythonDictionary(), new ModuleContext(new PythonDictionary(), DefaultContext.DefaultPythonContext));
            name = IronPython.Modules.Builtin.input(context, "What is your name?\n");
            IronPython.Modules.Builtin.print(context, "Hi, %s.", consoleio.name);
            System.GC.KeepAlive(pythonContext);
        }
    }
}

正确输出 "What is your name?",但随后在尝试解码输入时崩溃:未知编码:cp437。

现在我已经发现,编码是在 Src/StdLib/Lib/encodings/init.py 中初始化的 我找不到如何在普通 IronPython 运行(例如控制台主机)中加载此模块,因此我无法在 C# 程序中重现它。

我的目标是在没有动态调度的情况下调用 IronPython 函数。

更新。现在我也尝试这样做:

var engine = Python.CreateEngine();
this.ScriptDomainManager = HostingHelpers.GetDomainManager(engine.Runtime);

相同的结果

得出结论:编码模块在 IronPython 中的 Python 中实现(核心模块在 C# 中)。它始终与 IronPythonConsole 项目一起工作,因为它隐式地将标准库的 IronPython 源代码添加到 Python path。我只需要像这样明确指定 path

var options = new Dictionary<string, object> { ["SearchPaths"] = path };
var engine = Python.CreateEngine(options);