Reputation: 29041
I've written a custom powershell host that provides a winforms-based interactive shell. The examples MSDN were excellent and I was able to get something working in a few hours.
All of the standard built-in commands like dir, etc work as expected. However, when I try to launch another console app,like the FTP client, that app starts sending output to stdout. I can see this by changing the application type in VS from windows to console. As soon as I launch FTP from my interactive shell, FTP starts talking to the console window.
Anyone tackled this before? In C++ I could just redirect stdin and stdout and be done with it, but I don't see a way to do this in c#. Help!
update
Okay, anything I run that is not a built-in command immediately starts interacting with the console window.
Upvotes: 1
Views: 1325
Reputation: 35
For anyone trying to solve this problem 14 years later, this discussion has a solution based on digging through PowerShell code. You have to use reflection to set an undocumented property but otherwise it's simple:
// Use reflection to execute ConsoleVisibility.AlwaysCaptureApplicationIO = true;
Type conVisibilityType = Type.GetType("System.Management.Automation.ConsoleVisibility, System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
PropertyInfo propInfo =
conVisibilityType.GetProperty(
"AlwaysCaptureApplicationIO", BindingFlags.Static | BindingFlags.Public);
propInfo.SetValue(null, true);
Once you set that, stdout and stderr from native applications will be sent to your PSHostUserInterface just like output from PowerShell commands.
Upvotes: 1
Reputation: 29041
I have finally found a working example here! While it doesn't use the Powershell classes in the .NET framework, it does exactly what I need, including successfully capturing io from launched console apps.
Upvotes: 1
Reputation: 1515
Check this out, maybe it can help
Process p = new Process();
p.StartInfo.FileName = "netstat";
p.StartInfo.Arguments = "-a";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
System.Diagnostics.Debug.WriteLine(p.StandardOutput.ReadToEnd());
Upvotes: 1