本文主要是介绍C#通过进程调用外部应用的实现示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下...
以WINFORM应用程序为例,在C#应用程序中调用python程序(Matplotlib绘制图形程序),将调用PYTHON程序生成的窗口程序嵌入在WINFORM窗口中
窗口程序类
using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using Systemhttp://www.chinasem.cn.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; namespace MyForm { public partial class Form2 : DevComponents.DotNetBar.Office2007Form { private static log4net.ILog log = log4net.LogManager.GetLogger(typeof(Form2)); [DllImport("shell32.dll")] private static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, Int32 nShowCmd); private string pyFileName = @"code.py"; //需要在生成完文件后修改该参数值为生成的文件绝对路径 private string pyParamsfilePath = @"pyParams.dat"; private string args = "-u"; private string dataType = ""; public delegChina编程ate void UpdateUI();//委托用于更新UI Process p = null;//接收python程序进程,用于控制进程 Thread startload;//线程用于matplotlib窗体处理 IntPtr figure1;//图像句柄 #region 绘图事件Windows API调用 [DllImport("user32.dll")] public static extern IntPtr Findwindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewparent); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint); const int GWL_STYLE = -16; //const int WS_CAPTION = 0x00C00000; const int WS_CAPTION = 0x00CC0000; const int WS_THICKFRAME = 0x00040000; const int WS_SYSMENU = 0X00080000; [DllImport("user32")] private static extern int GetWindowLong(System.IntPtr hwnd, int nIndex); [DllImport("user32")] private static extern int SetW编程indowLong(System.IntPtr hwnd, int index, int newLong); [DllImport("user32")] private static extern int InvalidateRect(System.IntPtr hwnd, object rect, bool bErase); /// <summary>最大化窗口,最小化窗口,正常大小窗口 /// nCmdShow:0隐藏,3最大化,6最小化,5正常显示 /// </summary> [DllImport("user32.dll", EntryPoint = "ShowWindow")] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); #endregion /// <summary> /// 绘制图形按钮点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Draw3D(object sender, EventArgs e) { Create3DChart("Z"); } /// <summary> /// 创建3D图形 /// </summary> private void Create3DChart(string drawDataType) { if (processInfo.process != null) {//如果python程序进程不为null if (!processInfo.process.HasExited) {//如果当前进程没有被终止,未终止时值为false,终止时值为true processInfo.process.Kill(); } } dataType = drawDataType; //实例化线程,用来初次调用matlab,并把图像窗体放到winform startload = new Thread(new ThreadStart(RunPythonScript)); //开始线程 startload.Start(); } /// <summary> /// 关闭窗口时结束进程 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void Close3DChart(object sender, FormClosedEventArgs e) { if (processInfo.process != null) {//如果python程序进程不为null if (!processInfo.process.HasExited) {//如果当前进程没有被终止,未终止时值为false,终止时值为true processInfo.process.Kill(); } } } /// <summary> /// 调用python脚本绘制3D图形 /// </summary> public void RunPythonScript() php { log.Info($"开始绘图线程---{DateTime.Now.ToString()}"); int count50ms = 0; //获取python的绝对路径(将文件放在c#程序的debug文件夹中可以这样操作) string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + pyFileName; //创建进程 Process process = new Process(); //没有配置环境变量的话,可以写python.exe的绝对路径,如果配置了,直接写"python.exe"即可 process.StartInfo.FileName = SystemConfigClass.PythonPath; //设置python文件路径参数 string sArguments = path; //设置执行方式参数 sArguments += " " + dataType; sArguments += " " + Application.StartupPath + "\\" + pyParamsfilePath; sArguments += " " + args; log.Info($"绘图参数---{DateTime.Now.ToString()}:{sArguments}"); process.StartInfo.Arguments = sArguments;//设置命令行自变量 process.StartInfo.UseShellExecute = true;//设置直接从可执行文件创建进程 //process.StartInfo.RedirectStandardOutput = true;//设置应用程序输出写入进程(程序输出可在c#控制台显示) 调试时使用 //process.StartInfo.RedirectStandardInput = true;//设置应用程序输入读取进程(程序输入可读取进程输入) 调试时使用 //process.StartInfo.RedirectStandardError = true;//设置应用程序错误信息写入进程(程序错误输出可在c#控制台显示) 调试时使用 process.StartInfo.CreateNoWindow = true;//设置新窗口启动进程 process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//设置窗口隐藏启动 processInfo.process = process; process.Start();//进程开始 //process.BeginOutputReadLine();//在Process.StandardOutput异步读取数据 调试时使用 //process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived); //调试时使用 figure1 = IntPtr.Zero; //循环查找figure1窗体 while (figure1 == IntPtr.Zero) { //查找matplotlib的Figure 1窗体,安装PYQT组件后,查找类名Qt652QWindowIcon,未安装查找类名TkTopLevel figure1 = FindWindow("Qt652QWindowIcon", "Figure 1"); //延时50ms Thread.Sleep(50); count50ms++; //20s超时设置 if (count50ms >= 400) { //label1.Text = "matplotlib资源加载时间过长!"; return; } } //跨线程,用委托方式执行 UpdateUI update = delegate { ShowWindow(figure1, 0); //隐藏标签 //label1.Visible = false; //设置matlab图像窗体的父窗体为panel SetParent(figure1, PlotPanel.Handle); //获取窗体原来的风格 var style = GetWindowLong(figure1, GWL_STYLE); //设置新风格,去掉标题,不能通过边框改变尺寸 SetWindowLong(figure1, GWL_STYLE, style & ~WS_CAPTION & ~WS_THICKFRAME); //移动到panel里合适的位置并重绘 MoveWindow(figure1, 0, 0, PlotPanel.Width, PlotPanel.Height, true); //调用显示窗体函数,隐藏再显示相当于刷新一下窗体 ShowWindow(figure1, 5);android }; PlotPanel.Invoke(update); //再移动一次,防止显示错误 Thread.Sleep(100); MoveWindow(figure1, 0, 0, PlotPanel.Width, PlotPanel.Height, true); //process.WaitForExit();//等待退出 } } }
进程信息类
/// <summary> /// 进程信息类 /// </summary> public static class processInfo { public static Process process { get; set; } = null; }
系统设置类
/// <summary> /// 系统设置类 /// </summary> public static class SystemConfigClass { public static string PythonPath { get; set; } = @"D:\Python\python.exe"; /// <summary> /// /// </summary> /// <param name="dataFilePath>Application.StartupPath + "\\SystemConfig.DAT"</param> public static void SetSystemConfig(string dataFilePath) { if (File.Exists(dataFilePath)) { //如果文件存在 删除文件后保存文件 string content = ""; using (StreamReader dataFile = new StreamReader(dataFilePath)) { while ((content = dataFile.ReadLine()) != null) { content = content.ToString(); var tempArr = content.Split("^".ToCharArray()).ToList(); if (tempArr != null && tempArr.Count == 2) { SystemConfigClass.PythonPath = tempArr[1]; } else { SystemConfigClass.PythonPath = @"D:\Python\python.exe"; } } dataFile.Close(); dataFile.Dispose(); }; } } }
到此这篇关于C#通过进程调用外部应用的实现示例的文章就介绍到这了,更多相关C# 进程调用外部应用内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于C#通过进程调用外部应用的实现示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!