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. 使用说明
环境要求
- .NET Framework 4.7.2+ 或 .NET 5/6/7/8
- Python 3.6+ 已安装并添加到 PATH 环境变量
- 所需的 Python 包:json(标准库,无需额外安装)
配置说明
Python 路径配置:在 Form1.cs 中修改 pythonExecutable 变量
- 如果 Python 已在 PATH 中,使用
"python" - 否则使用完整路径,如
@"C:\Python39\python.exe"
脚本目录:确保 PythonScripts 目录与可执行文件在同一目录
功能特点
- 通过下拉框选择不同的 Python 脚本
- 实时显示执行状态
- 支持 JSON 格式的参数传递和结果解析
- 错误处理和超时控制
- 可打开脚本目录进行管理
扩展建议
- 添加参数输入界面,让用户可以自定义输入参数
- 添加脚本执行日志记录
- 支持批量执行多个脚本
- 添加 Python 环境检测功能
- 支持虚拟环境
以上就是C# WinForms程序调用Python脚本的完整代码案例的详细内容,更多关于C# WinForms调用Python脚本的资料请关注脚本之家其它相关文章!


最新评论