【发布时间】:2022-02-24 22:07:32
【问题描述】:
总的来说,我对 Python 和 .NET 还很陌生,但我决定问问更有能力的人,因为我一直在努力解决从 Windows 窗体执行 python 脚本的问题。
我的项目的基本思想是一个桌面应用程序,整体逻辑是从几个选定的复选框中读取,将这些选择的值传递给我的 python 脚本,从那里我生成一个基于这些的 Excell 表结果,并将此表显示回 Windows 窗体应用程序。
创建表格并管理在桌面应用程序中显示它已经完成,但是在执行脚本本身时,我在两个平台之间的通信方面遇到了严重问题。
我尝试过使用 IronPython,它运行良好,直到我发现 Iron Python 不支持 CPython 包,比如 Pandas,它是基于 numpy 构建的,而 numpy 显然是其中之一。我查看了很多关于这个问题的文章,答案似乎并不乐观,大多数建议都是使用 pythonnet。
我尝试实现pythonnet,遵循了许多文章,而我所做的一切,除了造成更大的混乱之外,什么都没有。
最后,我决定使用 C# Process 类,但也没有成功。
如果有任何有关如何解决此问题的 cmets 和建议,我们将不胜感激。
Python version: 3.7
Windows 10 (64 bit)
.NET Framework 4.7.2
这是我在 Windows 窗体中的一些代码尝试:
使用流程类实现
这里的问题是我无法运行这个脚本,因为它无法找到 python 脚本的包的错误消息
var processStartInfo = new ProcessStartInfo
{
Arguments = "C:\\Users\\Dobromir\\PycharmProjects\\pythonProject\\main.py",
FileName = "C:\\Python27\\python.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
Process.Start(processStartInfo);
使用 IronPython 实现(在使用 pandas 包之前就可以使用)
这里的问题是 CPython 包的限制和错误。
对于 IronPython,我必须降级到 Python 2.7 才能使用它。对于其余示例,我使用的是 Python 3.7
ScriptEngine pythonEngine = Python.CreateEngine();
var searchPaths = pythonEngine.GetSearchPaths();
searchPaths.Add(@"C:\Python27\Lib");
searchPaths.Add(@"C:\Users\Dobromir\PycharmProjects\pythonProject\venv\Lib\site-packages");
pythonEngine.SetSearchPaths(searchPaths);
List<String> argv = new List<String>();
argv.Add("Some Value1");
argv.Add("Some Value2");
ScriptSource pythonScript = pythonEngine.CreateScriptSourceFromFile("C:\\Users\\Dobromir\\PycharmProjects\\pythonProject\\main.py");
pythonEngine.GetSysModule().SetVariable("argv", argv);
pythonEngine.SetSearchPaths(searchPaths);
ScriptScope scope = pythonEngine.CreateScope();
pythonScript.Execute(scope);
pythonnet的实现 我在这里遇到的问题是使用 Py.GIL()。我相信它很难找到 python 文件,并且还尝试在变量 pathToPython 中提供 python37.dll。
我收到 Python.Runtime, Version=2.5.2.0, Culture=neutral....missmatch"
的错误string pathToPython = @"C:\Users\Dobromir\AppData\Local\Programs\Python\Python37";
string path = pathToPython + "; " + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONHOME", pathToPython, EnvironmentVariableTarget.Process);
Console.WriteLine(path);
var lib = new[]
{
@"C:\\Users\\Dobromir\\PycharmProjects\\App37\\main.py",
Path.Combine(pathToPython, "Lib"),
Path.Combine(pathToPython, "DLLs")
};
string paths = string.Join("; ", lib);
Environment.SetEnvironmentVariable("PYTHONPATH", paths, EnvironmentVariableTarget.Process);
using (Py.GIL()) //Initialize the Python engine and acquire the interpreter lock
{
try
{
Console.WriteLine("I am working");
}
catch (PythonException error)
{
Console.WriteLine("Error occured: ", error.Message);
}
}
我还尝试创建一个 bash 脚本来执行 python 脚本,并得到了 no module found 错误
我知道这些不是最好的实现,但要做好。
我的问题是,如果有人对如何使这个简单的操作工作有任何想法,我将非常感激,感谢您的时间和理解
P.S - 很抱歉这篇长文,想写下我在寻求帮助之前尝试过的东西,但如果有人更感兴趣,我会提供更多信息。
【问题讨论】:
-
您似乎希望脚本在 python 3.x 中运行,但您为 ProcessStartInfo 提供的路径适用于 python 2.7 版。也许通过版本 3.x 的路径,然后重试。
-
@yohannist 我提供的 ProcessStart 脚本将基本解释器设置为 python 2.7。但是无论如何尝试使用 3.x 运行它并没有工作。
标签: python c# .net ironpython python.net