【问题标题】:Write to stdin of a running process in windows写入 Windows 中正在运行的进程的标准输入
【发布时间】:2015-09-19 05:12:07
【问题描述】:

我想从 Windows 中的外部进程将数据写入现有进程的 stdin

我在 Linux 上发现了类似的问题,但我想知道如何在 Windows 中做同样的事情。

How to write data to existing process's STDIN from external process?

How do you stream data into the STDIN of a program from different local/remote processes in Python?

https://serverfault.com/questions/443297/write-to-stdin-of-a-running-process-using-pipe

我尝试使用此代码,但出现错误。我还尝试运行该程序,使用此代码向该程序发送stdin,但再次出错。

在 CMD 中:

type my_input_string | app.exe -start
my_input_string | app.exe -start
app.exe -start < pas.txt

在python中:

p = subprocess.Popen('"C:\app.exe" -start', stdin=subprocess.PIPE, universal_newlines=True, shell=True)  
grep_stdout = p.communicate(input='my_input_string')[0]

我得到的错误是:

ReadConsole() 失败:句柄无效。

在 C# 中:

try
{
    var startInfo = new ProcessStartInfo();
    startInfo.RedirectStandardInput = true;
    startInfo.FileName = textBox1.Text;
    startInfo.Arguments = textBox2.Text;
    startInfo.UseShellExecute = false;

    var process = new Process();
    process.StartInfo = startInfo;
    process.Start();
    Thread.Sleep(1000);
    var streamWriter = process.StandardInput;
    streamWriter.WriteLine("1");
}
catch (Exception ex)
{ 
    textBox4.Text = ex.Message+"\r\n"+ex.Source;
}

在 C# 中,使用上面的代码,App.exe(启动另一个进程的命令行应用程序)崩溃,但在 C# 应用程序中我没有任何异常。我认为这是因为UseShellExecute = false

如果我在运行 C# 应用程序时选择“不要在后台运行应用程序”,我可以找到该进程并使用sendkeys 向它发送my_input_string,但这不是一个好主意,因为用户在运行 GUI 时可以看到命令行。

我怎样才能发送stdin,只使用 CMD、python 脚本或 C#,没有任何错误?

【问题讨论】:

  • 呃,对不起,但我不知道……谁在给谁写信? Python 到 C#? C# 到 Python?你想要一般情况吗?
  • @NightShadeQueen 我想要一种从 python 或 C# 写入标准输入的方法,我尝试在 python 中编写脚本并从 C# 运行。
  • 查看我的this answer 中的errorwindow.py 模块,因为它完成了我认为您正在尝试做的事情。主要区别在于,一个进程的输出通过打印(或将其写入stderr)发送到另一个进程。在我的other answer 中,同样的模块也用于完成与相关问题类似的事情。

标签: c# python process cmd stdin


【解决方案1】:

如果您正在启动,然后从 c# 提供输入,您可以执行以下操作:

var startInfo = new ProcessStartInfo("path/to/executable");
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false;

var process = new Process();
process.StartInfo = startInfo;
process.Start();

var streamWriter = process.StandardInput;
streamWriter.WriteLine("I'm supplying input!");

如果您需要写入已经运行的应用程序的标准输入,我怀疑使用 .net 类很容易做到这一点,因为 Process 类不会为您提供 StandardInput(它会抛出 @987654323 @)

编辑: 为ProcessStartInfo()添加参数

【讨论】:

  • Thnx 为您的回答买我尝试,当我使用命令行程序崩溃!也不例外!你有什么别的想法吗?
  • 请在调试器中运行它并给我异常信息。
  • 更新问题,并添加图片,在 C# 中我没有任何异常!
  • 天哪,对不起。我遗漏了一个相当重要的步骤。见编辑。
  • 我看到并添加了 startinfo.filenamestartinfo.Arguments 我的异常 i 在启动停止后的其他进程中 Unhandled exception at 0x70FD6ECC (libxml2-2.dll) in client.exe: 0xC0000005: Access violation reading location 0x0000001C.
【解决方案2】:

这个问题已经有一段时间了,但我希望它对答案有所帮助。

我需要做类似的事情,使用 aircrack-ng 应用程序套件,该套件通过 STDIN 接收字符串,我找到的解决方案可在此链接中找到: C# output string to aircrack-ng

基本上你需要启动你的python应用程序,作为C#应用程序的一个子进程。

假设 python 应用程序正在等待 STDIN 写入,它看起来像这样:

public void WriteToAnotherProcess(string textToWrite)
{
    try
    {
        using (System.Diagnostics.Process FirstProcess = new System.Diagnostics.Process())
        {
            var startInfo = new ProcessStartInfo();

            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardInput = true;
            startInfo.FileName = textBox1.Text; // here the full path to the app that is waiting for the STDIN input
            startInfo.Arguments = textBox2.Text; //Arguments for second app
            startInfo.UseShellExecute = false;

            FirstProcess.StartInfo = startInfo;
            FirstProcess.Start();

            StreamWriter FirstProcessWriter = FirstProcess.StandardInput;
            StreamReader FirstProcessReader = FirstProcess.StandardOutput;

            FirstProcess.WriteLine(textToWrite);
            FirstProcess.Close();
            FirstProcess.WaitForExit();

            textBox4.Text = $"The return(STDOUT) from second app is: {FirstProcessReader.ReadToEnd()}";
        }
    }
    catch (Exception ex)
    {
        textBox4.Text = ex.Message + "\r\n" + ex.Source;
    }
}

如果您的应用程序在执行过程中崩溃,正如您所提到的,您可以使用以下属性: RedirectStandardErrorProcessStartInfo 中可用。

直接从 python 应用程序中获取错误返回,这样您就可以了解实际发生的情况

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2018-08-19
    • 2011-12-31
    • 2015-10-02
    • 1970-01-01
    • 2013-06-24
    相关资源
    最近更新 更多