C#通过进程调用外部应用的实现示例

2025-05-19 15:50

本文主要是介绍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#通过进程调用外部应用的实现示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154668

相关文章

使用Vue-ECharts实现数据可视化图表功能

《使用Vue-ECharts实现数据可视化图表功能》在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所... 目录前言为什么选择 vue-ECharts?1. 基于 ECharts,功能强大2. 更符合 Vue

Vue中插槽slot的使用示例详解

《Vue中插槽slot的使用示例详解》:本文主要介绍Vue中插槽slot的使用示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、插槽是什么二、插槽分类2.1 匿名插槽2.2 具名插槽2.3 作用域插槽三、插槽的基本使用3.1 匿名插槽

使用WPF实现窗口抖动动画效果

《使用WPF实现窗口抖动动画效果》在用户界面设计中,适当的动画反馈可以提升用户体验,尤其是在错误提示、操作失败等场景下,窗口抖动作为一种常见且直观的视觉反馈方式,常用于提醒用户注意当前状态,本文将详细... 目录前言实现思路概述核心代码实现1、 获取目标窗口2、初始化基础位置值3、创建抖动动画4、动画完成后

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

利用Python实现可回滚方案的示例代码

《利用Python实现可回滚方案的示例代码》很多项目翻车不是因为不会做,而是走错了方向却没法回头,技术选型失败的风险我们都清楚,但真正能提前规划“回滚方案”的人不多,本文从实际项目出发,教你如何用Py... 目录描述题解答案(核心思路)题解代码分析第一步:抽象缓存接口第二步:实现两个版本第三步:根据 Fea

Java应用如何防止恶意文件上传

《Java应用如何防止恶意文件上传》恶意文件上传可能导致服务器被入侵,数据泄露甚至服务瘫痪,因此我们必须采取全面且有效的防范措施来保护Java应用的安全,下面我们就来看看具体的实现方法吧... 目录恶意文件上传的潜在风险常见的恶意文件上传手段防范恶意文件上传的关键策略严格验证文件类型检查文件内容控制文件存储

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态:

python利用backoff实现异常自动重试详解

《python利用backoff实现异常自动重试详解》backoff是一个用于实现重试机制的Python库,通过指数退避或其他策略自动重试失败的操作,下面小编就来和大家详细讲讲如何利用backoff实... 目录1. backoff 库简介2. on_exception 装饰器的原理2.1 核心逻辑2.2

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

QT6中绘制UI的两种方法详解与示例代码

《QT6中绘制UI的两种方法详解与示例代码》Qt6提供了两种主要的UI绘制技术:​​QML(QtMeta-ObjectLanguage)​​和​​C++Widgets​​,这两种技术各有优势,适用于不... 目录一、QML 技术详解1.1 QML 简介1.2 QML 的核心概念1.3 QML 示例:简单按钮