Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write to stdin of a running process in windows

I want to write data to an existing process's stdin from an external process in Windows.

I found similar questions for Linux, but I want to know how I can do the same in 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

I tried with this code but I got an error. I also tried running the program, sending stdin to that with this code, but again, it errored.

In CMD:

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

In 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]

The error I get is:

ReadConsole() failed: The handle is invalid.

And in 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;
}

Screenshot of windows, front-most says "client.exe has stopped working".

In C#, with the code above, App.exe (command line application which starts the other process) crashes, but in C# application I don't have any exception. I think that is because of UseShellExecute = false.

If I choose "don't run app in background" when I run the C# app, I can find the process and use sendkeys to send my_input_string to it, but this isn't a good idea because the user can see the commandline when it's running the GUI.

How can I send stdin, only using CMD, a python script, or C#, without any errors?

like image 512
Sara Avatar asked Jul 01 '15 21:07

Sara


1 Answers

If you're launching, and then supplying the input from c#, you can do something like this:

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!");

If you need to write to the standard input of an application already running, I doubt that is easy to do with .net classes, as the Process class will not give you the StandardInput (it will instead throw an InvalidOperationException)

Edit: Added parameter to ProcessStartInfo()

like image 66
willaien Avatar answered Nov 04 '22 17:11

willaien