c# - 从 C# 应用程序运行 .py 时出现空白控制台输出
问题描述
我想做的是从我的 C# 应用程序运行 Python 脚本。
我在这里阅读了许多线程,并将以下代码放在一起:
private void RunPythonScript(string py1, string py2)
{
try
{
ProcessStartInfo start = new ProcessStartInfo
{
FileName = py1,
Arguments = py2,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
string stderr = process.StandardError.ReadToEnd();
Console.Write(stderr);
Console.Write(result);
}
}
}
catch (Exception ex)
{
Helpers.ReturnMessage(ex.ToString());
}
}
private void RunPythonScriptToolStripMenuItem_Click(object sender, EventArgs e)
{
string py1 = @"C:\Users\Graham\AppData\Local\Programs\Python\Python37-32\python.exe";
string py2 = @"C:\Users\Graham\Desktop\Files\programming\PaydayDreamsProgramming\Python\scripts\domain-seo-analyzer\domain_seo_analyzer.py";
RunPythonScript(py1, py2);
}
这似乎相当直截了当。
问题是:python.exe
命令控制台弹出空白,所以我假设脚本没有运行。没有我可以去的错误,只是一个空白的控制台框。
我的代码中有什么我遗漏的吗?(我假设这是一个 C# 错误) .exe 和 .py 的路径都是完全正确的。
我不确定还有什么要检查的,任何帮助将不胜感激。
解决方案
CommandLineProcess 类 - 启动命令行进程并等待它完成。捕获所有标准输出/错误,并且不会为该进程启动单独的窗口:
using System;
using System.Diagnostics;
using System.IO;
namespace Example
{
public sealed class CommandLineProcess : IDisposable
{
public string Path { get; }
public string Arguments { get; }
public bool IsRunning { get; private set; }
public int? ExitCode { get; private set; }
private Process Process;
private readonly object Locker = new object();
public CommandLineProcess(string path, string arguments)
{
Path = path ?? throw new ArgumentNullException(nameof(path));
if (!File.Exists(path)) throw new ArgumentException($"Executable not found: {path}");
Arguments = arguments;
}
public int Run(out string output, out string err)
{
lock (Locker)
{
if (IsRunning) throw new Exception("The process is already running");
Process = new Process()
{
EnableRaisingEvents = true,
StartInfo = new ProcessStartInfo()
{
FileName = Path,
Arguments = Arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
},
};
if (!Process.Start()) throw new Exception("Process could not be started");
output = Process.StandardOutput.ReadToEnd();
err = Process.StandardError.ReadToEnd();
Process.WaitForExit();
try { Process.Refresh(); } catch { }
return (ExitCode = Process.ExitCode).Value;
}
}
public void Kill()
{
lock (Locker)
{
try { Process?.Kill(); }
catch { }
IsRunning = false;
Process = null;
}
}
public void Dispose()
{
try { Process?.Dispose(); }
catch { }
}
}
}
然后像这样使用它:
private void RunPythonScriptToolStripMenuItem_Click(object sender, EventArgs e)
{
string pythonPath = @"C:\Users\Graham\AppData\Local\Programs\Python\Python37-32\python.exe";
string script = @"C:\Users\Graham\Desktop\Files\programming\PaydayDreamsProgramming\Python\scripts\domain-seo-analyzer\domain_seo_analyzer.py";
string result = string.Empty;
using (CommandLineProcess cmd = new CommandLineProcess(pythonPath, script))
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"Starting python script: {script}")
// Call Python:
int exitCode = cmd.Run(out string processOutput, out string processError);
// Get result:
sb.AppendLine(processOutput);
sb.AppendLine(processError);
result = sb.ToString();
}
// Do something with result here
}
如果您仍然遇到错误,请让我更新。
推荐阅读
- html - 使用base64转换将图像存储到本地存储,并显示在下一页,Angular 6
- javascript - 如何使用 document.getElementsByClassName 和 Element.classList 正确切换类
- python - Django 上的 Paho-mqtt 客户端
- html - Bootstrap 4 粘顶停止工作
- java - 使用java获取没有周末的特定日期之间的日期
- android - 合并 twilio 生成的两个 .mka 文件
- java - 查找单词中不重复字母的所有排列
- linux-device-driver - 在 Qemu 上编写用于 DMA 传输的 PCI 驱动程序
- informix - Informix - CREATE TABLE 上的语法错误
- unity3d - unity创建自定义MenuIItem