C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# WinForms调用Python脚本

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

作者:学亮编程手记

本文介绍了一个完整的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 变量

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

功能特点

扩展建议

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

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

您可能感兴趣的文章:
阅读全文