【问题标题】:Blank console output when running .py from C# application从 C# 应用程序运行 .py 时控制台输出空白
【发布时间】:2019-11-08 18:13:21
【问题描述】:

我想做的是从我的 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 的路径都是完全正确的。

我不确定还有什么要检查的,任何帮助将不胜感激。

【问题讨论】:

  • 看看这个answer,尤其是 CommandLineProcess 类:它与您正在寻找的类似,以更强大的方式,但它调用了另一个可执行文件(在这种情况下为 msbuild) .您可以根据需要调整该代码。
  • 另外,设置 Process.EnableRaisingEvents = true。
  • 我已经在下面发布了一个答案,如果它适合您的要求,请告诉我。
  • 您好抱歉耽搁了,效果很好非常感谢您,这让我困扰了好几天:)
  • 太好了,在这种情况下,请考虑对接受的答案进行投票。祝您编程愉快!

标签: c# python console


【解决方案1】:

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
}

如果您仍然遇到错误,请让我更新。

【讨论】:

    猜你喜欢
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    相关资源
    最近更新 更多