C# WinForms程序调用Python脚本的完整代码案例

 更新时间:2025年11月12日 09:12:52   作者:学亮编程手记  
本文介绍了一个完整的C# WinForms应用程序,该应用程序通过下拉框选择并执行不同的Python脚本,文章详细描述了项目结构、Python脚本准备、C#代码实现、使用说明和配置说明,并提供了功能特点和扩展建议,需要的朋友可以参考下

C# 上位机调用 Python 脚本的完整案例

下面是一个完整的 C# WinForms 应用程序,通过下拉框选择不同的 Python 脚本并执行。

1. 项目结构

PythonCallerApp/
├── PythonScripts/          # Python 脚本目录
│   ├── script1.py
│   ├── script2.py
│   └── script3.py
├── Form1.cs               # 主窗体
├── Form1.Designer.cs
└── Program.cs

2. Python 脚本准备

首先创建几个测试用的 Python 脚本:

script1.py - 简单的数学计算

import sys
import json

def main():
    # 接收参数
    if len(sys.argv) > 1:
        try:
            data = json.loads(sys.argv[1])
            number = data.get('number', 10)
        except:
            number = 10
    else:
        number = 10
    
    result = number * 2
    output = {
        "original_number": number,
        "doubled": result,
        "message": "数字已成功翻倍"
    }
    
    print(json.dumps(output))

if __name__ == "__main__":
    main()

script2.py - 字符串处理

import sys
import json

def main():
    if len(sys.argv) > 1:
        try:
            data = json.loads(sys.argv[1])
            text = data.get('text', 'Hello')
            repeat = data.get('repeat', 3)
        except:
            text = 'Hello'
            repeat = 3
    else:
        text = 'Hello'
        repeat = 3
    
    result = text * repeat
    output = {
        "original_text": text,
        "repeated": result,
        "repeat_count": repeat
    }
    
    print(json.dumps(output))

if __name__ == "__main__":
    main()

script3.py - 列表处理

import sys
import json

def main():
    if len(sys.argv) > 1:
        try:
            data = json.loads(sys.argv[1])
            numbers = data.get('numbers', [1, 2, 3, 4, 5])
        except:
            numbers = [1, 2, 3, 4, 5]
    else:
        numbers = [1, 2, 3, 4, 5]
    
    total = sum(numbers)
    average = total / len(numbers) if numbers else 0
    
    output = {
        "numbers": numbers,
        "sum": total,
        "average": average,
        "count": len(numbers)
    }
    
    print(json.dumps(output))

if __name__ == "__main__":
    main()

3. C# WinForms 应用程序

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Text.Json;

namespace PythonCallerApp
{
    public partial class Form1 : Form
    {
        // Python 脚本目录
        private string pythonScriptsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PythonScripts");
        
        // Python 执行器路径(根据你的环境修改)
        private string pythonExecutable = "python"; // 或者完整路径如 @"C:\Python39\python.exe"

        public Form1()
        {
            InitializeComponent();
            InitializeComboBox();
        }

        private void InitializeComboBox()
        {
            // 清空下拉框
            comboBoxScripts.Items.Clear();
            
            // 添加脚本选项
            comboBoxScripts.Items.Add(new ScriptItem("数字翻倍", "script1.py"));
            comboBoxScripts.Items.Add(new ScriptItem("文本重复", "script2.py"));
            comboBoxScripts.Items.Add(new ScriptItem("数字统计", "script3.py"));
            
            // 设置显示属性
            comboBoxScripts.DisplayMember = "DisplayName";
            comboBoxScripts.ValueMember = "ScriptName";
            
            // 默认选择第一项
            if (comboBoxScripts.Items.Count > 0)
                comboBoxScripts.SelectedIndex = 0;
        }

        private async void btnExecute_Click(object sender, EventArgs e)
        {
            if (comboBoxScripts.SelectedItem == null)
            {
                MessageBox.Show("请选择一个Python脚本!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            var selectedScript = comboBoxScripts.SelectedItem as ScriptItem;
            if (selectedScript == null) return;

            // 显示执行状态
            lblStatus.Text = "执行中...";
            lblStatus.ForeColor = Color.Blue;
            btnExecute.Enabled = false;

            try
            {
                string scriptPath = Path.Combine(pythonScriptsPath, selectedScript.ScriptName);
                
                if (!File.Exists(scriptPath))
                {
                    MessageBox.Show($"找不到脚本文件: {scriptPath}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 准备参数
                string arguments = PrepareArguments(selectedScript.ScriptName);
                
                // 创建进程启动信息
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = pythonExecutable,
                    Arguments = $"\"{scriptPath}\" {arguments}",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8,
                    StandardErrorEncoding = Encoding.UTF8
                };

                // 执行 Python 脚本
                using (Process process = new Process())
                {
                    process.StartInfo = startInfo;
                    
                    // 收集输出
                    StringBuilder output = new StringBuilder();
                    StringBuilder error = new StringBuilder();

                    process.OutputDataReceived += (s, args) => {
                        if (!string.IsNullOrEmpty(args.Data))
                            output.AppendLine(args.Data);
                    };

                    process.ErrorDataReceived += (s, args) => {
                        if (!string.IsNullOrEmpty(args.Data))
                            error.AppendLine(args.Data);
                    };

                    process.Start();
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();

                    // 等待进程完成(带超时)
                    bool completed = process.WaitForExit(30000); // 30秒超时

                    if (!completed)
                    {
                        process.Kill();
                        throw new TimeoutException("Python脚本执行超时");
                    }

                    // 处理结果
                    if (process.ExitCode == 0)
                    {
                        string result = output.ToString().Trim();
                        if (!string.IsNullOrEmpty(result))
                        {
                            try
                            {
                                // 尝试解析 JSON 输出
                                using JsonDocument doc = JsonDocument.Parse(result);
                                txtOutput.Text = JsonSerializer.Serialize(doc, new JsonSerializerOptions { WriteIndented = true });
                                
                                lblStatus.Text = "执行成功!";
                                lblStatus.ForeColor = Color.Green;
                            }
                            catch
                            {
                                // 如果不是 JSON,直接显示原始输出
                                txtOutput.Text = result;
                                lblStatus.Text = "执行完成!";
                                lblStatus.ForeColor = Color.Green;
                            }
                        }
                        else
                        {
                            txtOutput.Text = "脚本执行成功,但无输出。";
                            lblStatus.Text = "执行完成!";
                            lblStatus.ForeColor = Color.Green;
                        }
                    }
                    else
                    {
                        string errorMessage = error.ToString();
                        if (string.IsNullOrEmpty(errorMessage))
                            errorMessage = output.ToString();
                            
                        txtOutput.Text = $"执行失败 (退出代码: {process.ExitCode}):\n{errorMessage}";
                        lblStatus.Text = "执行失败!";
                        lblStatus.ForeColor = Color.Red;
                    }
                }
            }
            catch (Exception ex)
            {
                txtOutput.Text = $"发生错误: {ex.Message}";
                lblStatus.Text = "执行错误!";
                lblStatus.ForeColor = Color.Red;
            }
            finally
            {
                btnExecute.Enabled = true;
            }
        }

        private string PrepareArguments(string scriptName)
        {
            // 根据不同的脚本准备不同的参数
            var parameters = new Dictionary<string, object>();
            
            switch (scriptName.ToLower())
            {
                case "script1.py":
                    parameters["number"] = 25;
                    break;
                case "script2.py":
                    parameters["text"] = "Hello Python! ";
                    parameters["repeat"] = 3;
                    break;
                case "script3.py":
                    parameters["numbers"] = new List<int> { 10, 20, 30, 40, 50 };
                    break;
                default:
                    parameters["message"] = "Hello from C#";
                    break;
            }
            
            return JsonSerializer.Serialize(parameters);
        }

        private void btnOpenScriptDir_Click(object sender, EventArgs e)
        {
            // 打开脚本目录
            if (Directory.Exists(pythonScriptsPath))
            {
                Process.Start("explorer.exe", pythonScriptsPath);
            }
            else
            {
                MessageBox.Show($"脚本目录不存在: {pythonScriptsPath}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }

    // 脚本项类
    public class ScriptItem
    {
        public string DisplayName { get; set; }
        public string ScriptName { get; set; }

        public ScriptItem(string displayName, string scriptName)
        {
            DisplayName = displayName;
            ScriptName = scriptName;
        }

        public override string ToString()
        {
            return DisplayName;
        }
    }
}

Form1.Designer.cs

namespace PythonCallerApp
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.comboBoxScripts = new System.Windows.Forms.ComboBox();
            this.btnExecute = new System.Windows.Forms.Button();
            this.txtOutput = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.lblStatus = new System.Windows.Forms.Label();
            this.btnOpenScriptDir = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // comboBoxScripts
            // 
            this.comboBoxScripts.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.comboBoxScripts.FormattingEnabled = true;
            this.comboBoxScripts.Location = new System.Drawing.Point(12, 12);
            this.comboBoxScripts.Name = "comboBoxScripts";
            this.comboBoxScripts.Size = new System.Drawing.Size(200, 23);
            this.comboBoxScripts.TabIndex = 0;
            // 
            // btnExecute
            // 
            this.btnExecute.Location = new System.Drawing.Point(218, 12);
            this.btnExecute.Name = "btnExecute";
            this.btnExecute.Size = new System.Drawing.Size(75, 23);
            this.btnExecute.TabIndex = 1;
            this.btnExecute.Text = "执行脚本";
            this.btnExecute.UseVisualStyleBackColor = true;
            this.btnExecute.Click += new System.EventHandler(this.btnExecute_Click);
            // 
            // txtOutput
            // 
            this.txtOutput.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.txtOutput.Location = new System.Drawing.Point(12, 70);
            this.txtOutput.Multiline = true;
            this.txtOutput.Name = "txtOutput";
            this.txtOutput.ReadOnly = true;
            this.txtOutput.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.txtOutput.Size = new System.Drawing.Size(560, 319);
            this.txtOutput.TabIndex = 2;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 52);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(68, 15);
            this.label1.TabIndex = 3;
            this.label1.Text = "执行结果:";
            // 
            // lblStatus
            // 
            this.lblStatus.AutoSize = true;
            this.lblStatus.Location = new System.Drawing.Point(299, 16);
            this.lblStatus.Name = "lblStatus";
            this.lblStatus.Size = new System.Drawing.Size(55, 15);
            this.lblStatus.TabIndex = 4;
            this.lblStatus.Text = "就绪状态";
            // 
            // btnOpenScriptDir
            // 
            this.btnOpenScriptDir.Location = new System.Drawing.Point(497, 12);
            this.btnOpenScriptDir.Name = "btnOpenScriptDir";
            this.btnOpenScriptDir.Size = new System.Drawing.Size(75, 23);
            this.btnOpenScriptDir.TabIndex = 5;
            this.btnOpenScriptDir.Text = "打开目录";
            this.btnOpenScriptDir.UseVisualStyleBackColor = true;
            this.btnOpenScriptDir.Click += new System.EventHandler(this.btnOpenScriptDir_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(584, 401);
            this.Controls.Add(this.btnOpenScriptDir);
            this.Controls.Add(this.lblStatus);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtOutput);
            this.Controls.Add(this.btnExecute);
            this.Controls.Add(this.comboBoxScripts);
            this.MinimumSize = new System.Drawing.Size(600, 440);
            this.Name = "Form1";
            this.Text = "Python 脚本调用器";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private ComboBox comboBoxScripts;
        private Button btnExecute;
        private TextBox txtOutput;
        private Label label1;
        private Label lblStatus;
        private Button btnOpenScriptDir;
    }
}

Program.cs

using System;
using System.Windows.Forms;

namespace PythonCallerApp
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

4. 使用说明

环境要求

  1. .NET Framework 4.7.2+ 或 .NET 5/6/7/8
  2. Python 3.6+ 已安装并添加到 PATH 环境变量
  3. 所需的 Python 包:json(标准库,无需额外安装)

配置说明

Python 路径配置:在 Form1.cs 中修改 pythonExecutable 变量

  • 如果 Python 已在 PATH 中,使用 "python"
  • 否则使用完整路径,如 @"C:\Python39\python.exe"

脚本目录:确保 PythonScripts 目录与可执行文件在同一目录

功能特点

  • 通过下拉框选择不同的 Python 脚本
  • 实时显示执行状态
  • 支持 JSON 格式的参数传递和结果解析
  • 错误处理和超时控制
  • 可打开脚本目录进行管理

扩展建议

  1. 添加参数输入界面,让用户可以自定义输入参数
  2. 添加脚本执行日志记录
  3. 支持批量执行多个脚本
  4. 添加 Python 环境检测功能
  5. 支持虚拟环境

以上就是C# WinForms程序调用Python脚本的完整代码案例的详细内容,更多关于C# WinForms调用Python脚本的资料请关注脚本之家其它相关文章!

相关文章

  • Unity Shader实现裁切效果

    Unity Shader实现裁切效果

    这篇文章主要为大家详细介绍了Unity Shader实现裁切效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#用递归算法解决八皇后问题

    C#用递归算法解决八皇后问题

    在软件编程中,这种思路确是一种解决问题最简单的算法,它通过一种类似于蛮干的思路,一步一步地往前走,每走一步都更靠近目标结果一些,直到遇到障碍物,我们才考虑往回走。
    2016-06-06
  • WinForm中实现双向数据绑定的示例详解

    WinForm中实现双向数据绑定的示例详解

    在开发WinForm应用程序时,常常需要将数据模型与用户界面进行同步,传统的做法是手动监听UI变化并更新数据模型,这种方式不仅繁琐而且容易出错,为了解决这个问题,许多现代UI框架都支持双向数据绑定,本文介绍WinForm中实现双向数据绑定的示例,需要的朋友可以参考下
    2025-05-05
  • C# Newtonsoft.Json 的使用说明

    C# Newtonsoft.Json 的使用说明

    这篇文章主要介绍了C# Newtonsoft.Json 的使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • C#设置或验证PDF文本域格式的方法详解

    C#设置或验证PDF文本域格式的方法详解

    PDF中的文本域可以通过设置不同格式,用于显示数字、货币、日期、时间、邮政编码、电话号码和社保号等等。本文将介绍如何通过C#设置或验证PDF文本域格式,需要的可以参考一下
    2022-01-01
  • Unity UGUI实现滑动翻页直接跳转页数

    Unity UGUI实现滑动翻页直接跳转页数

    这篇文章主要为大家详细介绍了Unity UGUI实现滑动翻页,直接跳转页数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • c# 文件(夹)创建与删除

    c# 文件(夹)创建与删除

    删除文件夹,参数文件夹路径
    2009-07-07
  • C# 命名空间(Namespace)相关知识总结

    C# 命名空间(Namespace)相关知识总结

    这篇文章主要介绍了C# 命名空间(Namespace)的相关知识,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以参考下
    2020-06-06
  • C#中DataTable排序、检索、合并等操作实例

    C#中DataTable排序、检索、合并等操作实例

    这篇文章主要介绍了C#中DataTable排序、检索、合并等操作实例,其中详细介绍了DataTable.Select的一些注意问题和使用技巧等,需要的朋友可以参考下
    2014-04-04
  • 深入浅析c#静态多态性与动态多态性

    深入浅析c#静态多态性与动态多态性

    多态就是多种形态,也就是对不同对象发送同一个消息,不同对象会做出不同的响应。这篇文章主要介绍了c#静态多态性与动态多态性的相关知识,需要的朋友可以参考下
    2018-09-09

最新评论