process.start 是 c# 调用 python 脚本最直接方案,关键在正确传参、指定 python 路径、设置工作目录、处理编码与输出重定向,并避免频繁启停进程;复杂数据用 stdin 或临时文件,长期调用宜改用常驻服务+ipc。

用 Process.Start 启动 Python 脚本最直接,但别传参出错
多数场景下,C# 不需要“实时交互”,只是让 Python 跑完模型、吐出结果(比如 JSON 或文件路径),这时 Process.Start 是最快落地的方案。关键不是“能不能调”,而是参数怎么传、路径怎么写、环境怎么找。
常见错误现象:File not found(Python 解释器没找到)、ModuleNotFoundError(pip 包在 C# 进程里不可见)、中文路径乱码、参数含空格被截断。
- 显式指定 Python 可执行路径,别依赖
PATH:Process.Start("C:\Python39\python.exe", @"D:iinfer.py --input data.jpg") - 脚本路径和参数统一用
@""原始字符串,避免反斜杠转义;含空格的路径/参数必须加双引号:"--input "D:\my data\test.jpg"" - 设置
ProcessStartInfo.WorkingDirectory,否则import相对路径或模型权重加载会失败 - 若 Python 依赖虚拟环境,直接调用该环境下的
python.exe(如venvScriptspython.exe),别激活环境——C# 进程无法继承 shell 激活状态
需要读取 Python 实时输出?记得设 RedirectStandardOutput 和编码
模型推理可能耗时几秒到几十秒,用户界面要显示进度或日志,就得捕获 stdout。但默认是缓冲的,且 Python 默认编码可能和 C# 不一致(尤其 Windows 上 Python 3.8+ 用 UTF-8,而 .NET 默认 ANSI)。
- 必须同时设
UseShellExecute = false和RedirectStandardOutput = true,否则重定向无效 - 显式指定
StandardOutput编码:process.StandardOutput.Encoding = Encoding.UTF8(Python 端也确保 print 用 UTF-8) - 别用
ReadToEnd()等全部结束才读——模型卡住时 UI 就假死;改用BeginOutputReadLine()+OutputDataReceived事件流式处理 - 如果 Python 脚本用了
print("log", flush=True)或sys.stdout.flush(),C# 端才能及时收到,否则输出滞留在缓冲区
传复杂数据别拼接命令行,改用标准输入(stdin)或临时文件
当你要传一张 Base64 图片、一段长 JSON 或二进制 embedding,塞进命令行参数既不安全(长度限制、shell 注入风险)也不可靠(编码/截断)。这时候 stdin 是更干净的选择,或者约定一个临时目录存/读文件。
- 启用
RedirectStandardInput = true,然后用process.StandardInput.WriteLine(jsonString)发送数据;Python 端用sys.stdin.read()接收 - 注意:C# 写完要调用
process.StandardInput.Close(),否则 Python 的read()会一直阻塞(等待 EOF) - 临时文件方案更稳,尤其涉及大图像或模型中间态:C# 生成唯一文件名(如
Path.GetTempFileName()),传路径给 Python;Python 处理完再把结果写到另一个临时路径,C# 轮询或等子进程退出后读取 - 别用硬编码路径如
"C:\temp\input.json"——多实例并发会冲突;务必用Path.GetTempFileName()或Guid.NewGuid()构造隔离路径
模型加载慢?别每次启动新 Python 进程
如果你频繁调用(比如每秒几次),每次 Process.Start 都要初始化 Python 解释器、导入 PyTorch/TensorFlow、加载模型权重,延迟可能达 1–3 秒。这不是通信问题,是架构选择问题。
- 长期运行的 Python 子进程 + IPC 是解法:C# 启动一个常驻的 Python 服务(比如用
Flask或ZeroMQ),通过 HTTP 或 socket 发请求,复用已加载的模型 - 更轻量可选
NamedPipeServerStream(Windows)或 Unix Domain Socket(Linux/macOS),C# 和 Python 各自连管道,实现低开销双向通信 - 别低估序列化成本:用
msgpack替代 JSON 传大量 tensor 数据,体积小、解析快;Python 端用msgpack.unpackb(data, raw=False),C# 用MsgPack.Cli - 如果只是偶尔调用、模型小(如 ONNX Runtime 轻量推理),老实用
Process.Start,别过早优化
跨语言调用真正难的不是“通不通”,而是错误是否可观察、超时是否可控、资源是否可回收。比如 Python 进程卡死,C# 得有 WaitForExit(5000) + Kill() 保底;又比如模型 OOM 导致 Python 崩溃,C# 要检查 ExitCode != 0 并读取 StandardError 才能定位。这些细节比“怎么启动”重要得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











