C# 调用Python
一、安装类库 pythonnet
谨慎使用IronPython,好像默认是2.7,运行部分外部引入的第三方包会报错
二、创建pyd 文件供c#调用
2.1 安装cython
pip install cython
2.2 准备自己的python文件
HtmlToMD.py
import sys
import html2text as ht
def change(htmlPath, mdPath):
print(htmlPath, mdPath)
try:
text_maker = ht.HTML2Text()
# 读取html格式文件
with open(htmlPath, 'r', encoding = 'utf-8') as f:
htmlpage = f.read()
# 处理html格式文件中的内容
text = text_maker.handle(htmlpage)
# 写入处理后的内容
with open(mdPath, 'w', encoding='utf-8') as f:
f.write(text)
return '成功将Html 转换为 MarkDown文件'
except Exception as err:
return '失败:' + err
2.3 创建setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("HtmlToMD.py"))
2.4 将需要编译的 HtmlToMD.py 和setup.py 放在同一个目录下,执行如下命令
python setup.py install
可以看到在当前目录的build/lib.win-amd64-3.10中生成了HtmlToMD.cp310-win_amd64.pyd文件。
三、将生成的文件放入C#项目下,并设置随项目生成而始终复制
四、编写代码,运行
pathToVirtualEnv 请使用个人本地的python环境目录,也可以使用虚拟环境
string htmlPath = @"K:\SVNProject\learningdocuments\第三期-架构师班\2--【第二章 分布式中间件】\大数据搜索中间件Elasticsearch\分布式中间件-Elasticsearch基础课件.html";
string mdPath = @"K:\SVNProject\learningdocuments\第三期-架构师班\2--【第二章 分布式中间件】\大数据搜索中间件Elasticsearch\分布式中间件-Elasticsearch.md";
//HtmlTo.MakeDown(htmlPath, mdPath);
//Console.WriteLine("完成HTML 转换为 MarkDown 操作");
//Console.ReadKey();
string pathToVirtualEnv = @"D:\Python\Python310";
Environment.SetEnvironmentVariable("PATH", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONPATH", $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib", EnvironmentVariableTarget.Process);
Runtime.PythonDLL = @"D:\Python\Python310\python310.dll";
PythonEngine.PythonHome = pathToVirtualEnv;
PythonEngine.PythonPath = PythonEngine.PythonPath + ";" + Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);
PythonEngine.Initialize();
using (Py.GIL())
{
dynamic np = Py.Import("HtmlToMD");
var result = np.change(htmlPath, mdPath); //调用change方法
Console.WriteLine(result);
}
Console.ReadLine();
运行效果:
设置解释:
-
设置
Runtime.PythonDLL
属性,即pythonxx.dll路径,xx为版本号 -
设置
PythonEngine.PythonHome
,即python.exe所在路径 -
设置
PythonEngine.PythonPath
,python脚本所在目录,可以放置多个路径,以分号隔开,但是pathToVirtualEnv\Lib\site-packages和pathToVirtualEnv\Lib应放在最后 -
调用
PythonEngine.Initialize();
五、直接使用python文件运行
python文件必须放在PythonEngine.PythonPath
设定的目录下,可以加入程序存放目录如(PythonProject是存放py文件位置):
PythonEngine.PythonPath = $"{Environment.CurrentDirectory}/PythonProject"
+ PythonEngine.PythonPath + ";"
+ Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process); //Lib Lib/site-packages
test.py
def hello():
print("hello")
def add(a,b):
return a+b
执行代码:
using (Py.GIL())
{
dynamic test = Py.Import("test");
test.hello();
}
六、问题
6.1 程序平台问题
Win32Exception: %1 不是有效的 Win32 应用程序。
原因是目标平台需要为x64,优先32或者AnyCPU都可能出现问题
改成下图配置即可: