C# 和 Python 之间的进程间通信

本文关键字:进程间通信 之间 Python | 更新日期: 2023-09-27 18:36:41

我可以理解关于这个话题有很多问题,但没有一个能真正解决我的问题。所以在这里我展示了我的代码,我希望在这里指出我的错误。

我有一个用C#编写的程序,它应该调用python可执行文件/文件。第一个要求是我通过输入流将一个参数传递给 python 文件。这个我能做到。我现在面临的真正问题是,我必须查看我的python文件是否正在打印"请输入argument_x",我必须在C#代码中读取此输出并检查它是否argument_x,然后只将参数值写入输入流中。下面是 C# 和 Python 的代码片段。

C# 代码如下所示:

using System;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create a new process object
            Process myProcess = new Process();
            //Provide the start information for the process
            myProcess.StartInfo.FileName = "python.exe";
            myProcess.StartInfo.Arguments = "mytestpython.py";
            myProcess.StartInfo.UseShellExecute = false;
            myProcess.StartInfo.RedirectStandardInput = true;
            myProcess.StartInfo.RedirectStandardOutput = true;
            StreamReader myStreamReader;
            StreamWriter myStreamWriter;
            //Invoke the process from current process
            myProcess.Start();
            myStreamReader = myProcess.StandardOutput;
            //Read the standard output of the spawned process.
            string myString = myProcess.StandardOutput.ReadToEnd();
            Console.WriteLine(myString);
            if (myString.Contains("argument_x"))
            {
                myStreamWriter = myProcess.StandardInput;
                String argument = "argument_value";
                myStreamWriter.WriteLine(argument);
            }
           myProcess.WaitForExit();
           myStreamWriter.Close();
           myStreamReader.Close();
           myProcess.Close();
      }
   }
}

mytestpython.py 文件中的 python 程序如下所示:

import sys
import getpass
prompt_string = "Please enter argument_x"
if sys.stdin.isatty():
    reqd_arg = getpass.getpass(prompt=prompt_string)
else:
    print(prompt_string)
    reqd_arg = sys.stdin.readline().rstrip()

请帮助我,因为我觉得我已经正确编写了 90% 的代码,中间有一个小错误。提前感谢您的帮助。

C# 和 Python 之间的进程间通信

当你执行myProcess.StandardOutput.ReadToEnd();时,它会尝试读取到Python程序的标准输出的末尾,这意味着它将等待Python程序完成执行并关闭其标准输出流,它永远不会这样做,因为它正在等待来自C#程序的输入。这会导致死锁。

当父进程等待子进程完成时,ReadToEnd()很有用。在交互式进程通信的情况下,您应该真正考虑使用异步通信BeginOutputReadLine请查看此处的 MSDN 文档以获取帮助

我修改了 C# 代码以接受 CLI 参数并在提示时传递密码,如下所示:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Diagnostics;
    using System.ComponentModel;
    namespace Stub
    {
      class Program
        {
          static void Main(string[] args)
            {
            // Declare variables and initialize
            string passWord = string.Empty;
            string processArgs = getArguments(args); //Call getArguments method
            Console.Write("Please enter the system password : ");
            passWord = readPassword(); //call readPassword method
            Process p = new Process();
            p.StartInfo.FileName = "myexe.exe";
            p.StartInfo.Arguments = processArgs;
            p.StartInfo.WorkingDirectory = "my_working_directory";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.Start();
            StreamWriter sw = p.StandardInput;
            StreamReader sr = p.StandardOutput;
            writePassword(sr, sw, "password", passWord);
            sw.Close();
            sr.Close();
            p.WaitForExit();
            p.Close();
    }
    static string getArguments(string[] args)
    {
        StringBuilder procArgs = new StringBuilder();
        foreach (string arg in args)
        {
            procArgs.Append(arg);
            procArgs.Append(" ");
        }
        return procArgs.ToString();
    }

    static void writePassword(StreamReader sr, StreamWriter sw, string keyWord, string passWord)
    {
        string mystring;            
        do
        {
            mystring = sr.ReadLine();
        } while (!mystring.Contains(keyWord));
        if (mystring.Contains(keyWord))
            sw.WriteLine(passWord);
        else
            sw.WriteLine("'r'n");
    }
    static string readPassword()
    {
        string pass = string.Empty;
        ConsoleKeyInfo key;
        do
        {
            key = Console.ReadKey(true);
            if (key.Key != ConsoleKey.Backspace)
            {
                pass +=key.KeyChar;
                Console.Write("*");
            }
            else
            {
                if (pass.Length > 0)
                {
                    pass = pass.Substring(0, (pass.Length - 1));
                    Console.Write("'b 'b");
                }
            }
        } while (key.Key != ConsoleKey.Enter);
        return pass;
    }
}

}

然后只是在Python中进行一个小的修改,如:

    import sys
    import getpass
    prompt_string = "Please enter password"
    if sys.stdin.isatty():
        reqd_arg = getpass.getpass(prompt=prompt_string)
    else:
        print(prompt_string)
        sys.stdout.flush()
        reqd_arg = sys.stdin.readline().rstrip()

瞧..!!有效