发布于2026-07-08 阅读(0)
扫一扫,手机访问
用 Process 拉起 Python 解释器,是跨语言调用中最稳妥的路径。没什么花哨,就是老老实实启动一个 python.exe 进程,通过标准输入输出管道通信。关键点有几个:python.exe 路径得对,最好指定绝对路径;脚本也建议用绝对路径,免得工作目录搞鬼;别忘了把 UseShellExecute 设为 false,不然重定向 IO 就没戏了;参数拼进 Arguments 字符串,别塞到 FileName 里。另外,加个 -u 参数能强制 Python 无缓冲输出,输入输出统一用 JSON 格式最省心。超时、读 stderr、检查 ExitCode——这三样少一个,线上就可能出幺蛾子。

Process 启动 Python 解释器是最直接的方式别走弯路——Assembly.LoadFrom 或者 IronPython 那种内嵌解析器的玩法,除非你有特殊理由,否则绝大多数场景下,Process 就是最稳定、兼容性最好、调试最直观的选择。本质就是额外启动一个独立的 python.exe 进程去跑脚本,C# 这边通过标准输入输出管道跟它对话。
几个躲不开的坑:
python.exe 得在系统 PATH 里,或者你直接给完整路径(比如 C:\Python39\python.exe)FileNotFoundErrorUseShellExecute = false 必须设,否则 stdin/stdout 重定向无效Arguments 字符串,别顺手塞进 FileNamevar startInfo = new ProcessStartInfo
{
FileName = "python.exe",
Arguments = $"\"{scriptPath}\" --input data.json",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
using var proc = Process.Start(startInfo);
string output = proc.StandardOutput.ReadToEnd();
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode != 0) throw new InvalidOperationException($"Python failed: {error}");
C# 读不到返回值?十有八九是 Python 那边没把结果真“吐出来”。Python 默认对 stdout 做行缓冲(遇到换行才刷出),子进程模式下可能完全不缓冲或全缓冲,结果 C# 一直 ReadToEnd() 阻塞,要么读到空字符串。
解决办法:
-u 参数强制无缓冲:python.exe -u script.pyprint(..., flush=True)input() 交互式语句,否则进程卡死等用户输入示例 Python 脚本(calc.py):
import json
import sys
# 解析命令行参数(简单起见,只取第一个)
if len(sys.argv) > 1:
try:
x = float(sys.argv[1])
result = {"status": "success", "value": x ** 2}
except Exception as e:
result = {"status": "error", "message": str(e)}
else:
result = {"status": "error", "message": "missing arg"}
print(json.dumps(result), flush=True)
用空格或制表符分隔参数,一旦遇到带空格的路径、JSON 字符串或者用户输入,立刻崩。C# 拼接 Arguments 字符串时容易漏转义,Python 端 sys.argv 解析也跟着脆弱。
更健壮的做法:
sys.stdin 读取并解析System.Text.Json.JsonSerializer.Deserialize() 解析C# 端发送 JSON 输入示例:
var inputJson = JsonSerializer.Serialize(new { a = 5.5, b = "test" });
startInfo.RedirectStandardInput = true;
using var proc = Process.Start(startInfo);
using var writer = proc.StandardInput;
writer.WriteLine(inputJson); // 注意换行,Python 的 input() 或 sys.stdin.readline() 依赖它
writer.Close();
没设超时,Python 脚本死循环或卡住,整个 C# 线程就跟着挂了;中文乱码是因为 Python 默认用系统编码(如 GBK),而 C# 的 Process 默认用 UTF-8;捕获不到异常,错误信息全丢进黑洞。
实操要点:
WaitForExit(milliseconds) 而不是无参版;超时后主动 Kill()startInfo.StandardOutputEncoding = Encoding.UTF8 和 StandardErrorEncoding,并确保 Python 脚本也用 UTF-8 输出(print(..., flush=True) 在 UTF-8 环境下默认正常)StandardError)必须读,否则进程可能因 stderr 缓冲满而僵死python3 而非 python,跨平台部署要判断环境真正上线时,这些不是可选项,是必填项。尤其是 stderr 不读、不设超时、不检查 ExitCode——问题一定在半夜出现。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8