由于项目原先架构在C#中的wimform,但是又需要数学拟合,C#中拟合代码写了很久还是搞不定,就用python写了拟合的代码,接下来就是如何用C#调用python文件了,好了,开始爬坑之旅。
首先,在VS2022中我用anoconda创建的python3.7环境,在VS2022中调试的python代码运行正常,然后就先参考武林大皮虾的帖子((36条消息) c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)_武林大皮虾的博客-优快云博客_c#调用pythonhttps://blog.youkuaiyun.com/qq_42063091/article/details/82418630)。自己先跑了下他的代码。结果啥都没有,控制台也没有返回任何结果,我直接好家伙。
接着又参考知乎上MiLoser大神的帖子(c#.Net如何外部调用Python对其传参并进行IO交互? - 知乎 (zhihu.com)https://www.zhihu.com/question/498292449/answer/2220038827),手动的将他ProcesHelper和ExceptionHelper添加到项目中,运行交互,ok。直呼nice!
那就试试运行武林大皮虾的main.py
# -*- coding: utf-8 -*-
#main.py
import numpy as np
import multi
import sys
def func(a,b):
result=np.sqrt(multi.multiplication(int(a),int(b)))
return result
if __name__ == '__main__':
print(func(sys.argv[1],sys.argv[2]))
结果死掉了,主要是他报numpy出错。
可是在anoconda prompt中,又能找到已经安装这些模块。
用VS2022运行也没有问题。没办法,再根据这个报错,找到了这篇帖子:(36条消息) import numpy时报错,怎么解决?-Python-优快云问答
可能是由于我是通过VS2022中创建的conda的环境,而且当时勾选了安装numpy库,按上面的帖子重装setuptools numpy,再次运行ok。
总结下来,在VS2022中,直接安装python库,bug有点多。可能是环境变量这些原因。VS2022中import可能没问题,但还是最好在cmd窗口中验证下。
我设定conda自己的python为当前的环境变量后,在cmd中验证,import numpy。
将C#中代码,修改
private void 启动pyToolStripMenuItem_Click(object sender, EventArgs e)
{
//读取python文件
var open = new OpenFileDialog();
open.Filter = "py|*.py";
if (open.ShowDialog() != DialogResult.OK)
{
return;
}
//执行python文件
string path1 = "D:\\C#\\netCallpyFileCopy\\ProcessPython\\bin\\Debug\\test.xlsx";//自己的excel文件路径
string args0 = $" {open.FileName} --action 1";
string args1 = $" {open.FileName} {path1}";
string args2 = $" {open.FileName} {2} {3}";
string exePath = @"C:\Users\zhang\.conda\envs\mypython37\python.exe";//VS2022中用conda创建的python37环境
string exePath1 = @"C:\ProgramData\Anaconda3\python.exe";//当前默认python
string exePath2 = @"C:\Program Files(x86)\Microsoft Visual Studio\Shared\Python39_64\python.exe";//VS2022自己安装的python
//server.Run("python", args0);//选MiLoser的 main.py文件时,运行代码
server.Run("python", args1);//选我自己的test.py文件时,运行的代码
//server.Run(exePath, args2);//选武林大皮虾main0.py文件时,运行的代码
//目前的Run无任何返回值,如只需要返回值,建议python代码中不要有任何print代码,
//只有最后return参数,main中一定要用print来返回到C#代码中
}
再一次运行C#的代码,搞定ok。
为了能够直接在C#中,直接返回python的计算结果,需要在ProcessServier中修改,将process.BeginOutputReadLine()修改为process.StandardOutput.ReadToEnd(),并返回结果output。需要注意的是,如果只需要python的最终结果,python代码中其他地方一定不要有print函数,只在main中print即可。
try
{
process.Start();
process.BeginOutputReadLine();//如果不需要python同步显示在C#界面里,此行代码可以注释掉,用process.StandardOutput.ReadToEnd()来获取最终的返回结果即可
process.BeginErrorReadLine();
this._process = process;
//string output = process.StandardOutput.ReadToEnd();
//return output; //output即为python程序运行的结果
}
catch (Exception ex)
{
this.ErroReceived(process, ex.GetInnerExceptionMessage());
//return(ex.GetInnerExceptionMessage()); //output即为python程序运行的结果
}
再次感谢各位大神,助我解决各种问题,参考链接有:
https://www.zhihu.com/question/498292449/answer/2220038827
http://www.cdadata.com/14300
https://blog.youkuaiyun.com/qq_42063091/article/details/82418630
https://www.cnblogs.com/ludage/p/12461403.html
https://blog.youkuaiyun.com/qq_36323164/article/details/123866646
https://blog.youkuaiyun.com/ShyLoneGirl/article/details/114171320
https://ask.youkuaiyun.com/questions/7411645
全部项目的代码放到Github上了: