How Can I Get the Output Stream in Powershell? - c#

I'm wanting to know if it's possible to get the stream that refers to the Powershell console window (in Powershell), assuming one exists. For example, in C# .NET it would be done simply by Console.OpenStandardOutput(). Is there an equivalent in Powershell?
What I'm looking to do is create a System.IO.BinaryWriter to write to it instead of using Write-Host or the like, mostly for experimentation.
I've tried [Console]::OpenStandardOutput(), but that gives me an empty stream, making me think a different one is in use for Powershell.
I'm working with Powershell V5.0:
Major Minor Build Revision
----- ----- ----- --------
5 0 10240 16384

(Note: PowerShell ISE doesn't use the console, so writing to the stream also won't have any effect.)
Trying to read from the standard output stream won't get you anywhere, it's meant for writing stuff to.
Neither will inspecting the length, as the standard output writer will immediately pick up any input and write it to the screen buffer.
Try this in a console-based host (ie. powershell.exe):
$TestBytes = "Test`n".ToCharArray() -as [byte[]]
$OutStream = [console]::OpenStandardOutput()
$OutStream.Write($TestBytes,0,$TestBytes.Length)
You should see that the string Test is written to the screen (along with a trailing newline)

Related

How do I write to file descriptor 3 instead of stdout in .NET 6 on Linux?

I'm using .NET 6 on Ubuntu 22.04. What is the equivalent C# code to the following Bash code?
echo 'Hello, World!' >&3
Normally, in C# I'd use code like Console.WriteLine("Hello, World!"); to write to stdout. But here, I need to write to file descriptor 3 instead of stdout.
I was able to find some Stack Overflow answers, but they're quite old and deal with Windows APIs which I don't think applies to what I'm trying to do.
I should clarify too that for my use case, redirecting standout output to another file descriptor as I start the .NET process isn't an option. This is is because I need to be able to write to stdout for one purpose, stderr for another, and file descriptor 3 for another. Three purposes in total. This is because the process must be able to be started by a framework that deals with stdout, stderr, and file descriptor 3 these ways. It needs to be compatible.
You should be able to achieve this by writing to /proc/self/fd/3
Use a StreamWriter:
using (StreamWriter outputFile = new StreamWriter("/proc/self/fd/3"))
{
outputFile.WriteLine("Test");
}
Otherwise, you could make a system call to echo, using the command you referenced above, or this...
Process.Start(#"echo Test > /proc/self/fd/3");

Why is there Console.Error() in C#, but no Console.Warning?

In C#, if we want to output an error to the console, we can simply write:
Console.Error.Write("Error!");
But when I try to write a warning to the console, I found that there isn't any:
Console.Warning.Write("Warning!");
Instead, I need to write:
WarningException myEx = new WarningException("This is a warning");
Console.Write(myEx.ToString());
Why is it designed this way?
Because Console is adapting to a much older idiom - where every process has 3 streams associated with it at startup - one standard input stream, one standard output stream, and one standard error stream.
(The standard names here are Console.In, Console.Out and Console.Error are their names in the .NET world, not stdin, stdout & stderr as in C.)
This is no standard warning stream.
Be aware that if you use output redirection when running a console application >file1.txt will redirect the standard output to file1.txt but an error output will continue to be shown on the console. (You use 2>something to redirect the standard error output or 2>&1 to redirect it to the same place that standard output is going to)

Redirecting C# Standard Output and Reading it with Python

I'm trying to redirect that standard output from a Command Line Project I wrote in C# and reading through the data in a Python file.
Currently, the C# application writes data that it reads from a sensor into a CSV file. I have to run the Python file later to get and process the data (has to be done in Python and the data collection has to be done in .NET to use the SDK).
I want to be able to run the C# and the Python projects at the same time and transfer the stream of data directly from the C# to Python project without the use of an intermediate, local file (the CSV).
I've done my own hunting on SO and in the MSDN Documentation. I'm looking at using the ProcessStartInfo.RedirectStandardOutput Property to redirect the console output of the C# application.
I don't yet know how to pick up on the data in this Stream from a Python file. This article was helpful in grasping a better understanding of how to approach it, but I'm still stuck.
I'm also looking at subprocess.Popen.communicate in Python but I'm not yet sure if that would work for what I am asking.
Any help would be appreciated.
Thanks to #Quantic for providing some great resources. Using subprocess.Popen, I can run the built .exe of my C# project and redirect the output to my Python file. I am able now to print() to output to the Python console all the information being output to the C# console (Console.WriteLine()).
Python code:
from subprocess import Popen, PIPE, STDOUT
p = Popen('ConsoleDataImporter.exe', stdout = PIPE, stderr = STDOUT, shell = True)
while True:
line = p.stdout.readline()
print(line)
if not line:
break
This gets the console output of the .NET project line by line as it is created and breaks out of the enclosing while loop upon the project's termination.

GhostScript printing Parameters

I am having big problems trying to print a PDF file in Windows using Ghostscript. The 'in Windows' argument comes from the fact that I am trying to use MS Windows default driver for this '-sDEVICE=mswinpr2'. I need all windows printers/drivers support. Also I can not use the PDF to images then to print job kind of solution. I cant use the gswin64c.exe file also, and I need that the job is done without any popups (no form of any kind). All I can do is just to send some parameters to gsdll32.dll and it to create a print job.
I am using C# wrapper
https://github.com/mephraim/ghostscriptsharp/tree/master
I am sending the following parameters: "-dBATCH -dNOPAUSE -dNOPROMPT -dDEVICEWIDTHPOINTS=612 -dDEVICEHEIGHTPOINTS=792 -dFIXEDMEDIA -dPDFFitPage -sDEVICE=mswinpr2 -dQUIET -sOutputFile=\"%printer%Epson Stylus Pro 4900\" D:\1.pdf"
And every time the printer selection dialog keeps popping up. I understand that the order the parameters are in matters .... because I changed it and it had different results.
Actual Question:
What parameters do I have to send to GhostScript dll so that I can print a PDF file using the default MS Windows printing driver.
Have you tried this using the command line version of GS instead of the DLL or C# thingy ? I'd suggest you concentrate on getting that to work first.
What is the name of the printer (as it appears in Windows) ?
What version of Ghostscript are you using ?
Try using the command line without '-dBATCH', '-dNOPAUSE', '-dNOPROMPT', '-dQUIET'. that way if Ghostscript tries to tell you something you won't just ignore it or miss it.
If the command line works then; I see you've escaped the " characters, but not the '%', you might want to escape those, or double them up. Depending how this wrapper of yours works they might be getting read as format specifiers.
The parameters used in the command line have been verified first in the command line version gswin64c.exe (64 bit operation system) and they work fine.
I am using GS version 9.10 (latest version).
I've tried different combinations of parameters, with or without some of them ... same result ... -100 exit code (general fault with no specification of the error that caused it).
It doesn't seem to be a problem with that % character... I'll try some more things.
Thanks Ken for the help
As far as the printer dialog popup is concerned, if you replace "mswinpr2" with the a compatible device name such as ljet4, the prompts would go away. My guess is that your computer must be having more than one printer installed and hence windows prompts for you to choose one from the list.

Standard Input & Output in .NET

How can I read from standard input and write to standard output. System.Diagnostics.Process.StandardInput's MSDN reference didn't help as it separately starts the process and then redirects the Standard Input/Output but what If the process is already running and called my Application to feed it some data. Here's an example to make things a bit clear:
I am simply using Unix pipes i.e. cat command in cygwin (A Linux like Environment for windows) that basically just reads standard input and print to standard output. following is the command:
% cat input/sample.txt | src/csharp/maptest
But that doesn't seems to work.
If some one know ruby here as i don't here's what i want to do the same in C#:
#!/usr/bin/env ruby
STDIN.each_line
do |line|
some code here
end
And here's some python equivalent code that i want to accomplish in c# or vb.net:
#!/usr/bin/env python
import re
import sys
for line in sys.stdin:
val = line.strip()
Any solutions?
Thanks in advance.
You're looking for the static methods in the Console class :
System.Console.In encapsulate the standard input stream
System.Console.Out encapsulate the standard output stream
Pointers to documentation for System.IO.Pipes are a red herring here.
If you just want the ability to have a process pipe its standard output to another process's standard input, then this works the same as you would expect provided the target process is written to read input from standard input. For example I can do
dir /b /s c:\*.* | findstr exe
to find all executable files on my C: drive.
All you need to do therefore is to build your maptest application so that it reads from standard input, in other words it must accept input via the Console.Read* methods as mentioned in other answers. See this previous question for an earlier discussion
C# Console receive input with pipe
You can't use Console.ReadLine() and Console.WriteLine()?
Never mind the above. Have you tried System.IO.Pipes? Here's the MSDN documentation.

Categories

Resources