Standard input/output in C# process - c#

My application App is using other my application SubApp.
When App needs SubApp it is creating process with SubApp, putting data to SubApp stdin and reading from SubApp stdout.
The problem is that SubApp is using some library which sometimes writes to stdout.
Fragment of SubApp code:
OutsideLibrary.DoSomeInitialization(); // <-- this sometimes writes to stdout
Stream input = Console.OpenStandardInput();
Stream output = Console.OpenStandardOutput();
data = (dataFormat)formatter.Deserialize(input);
//do some job
formatter.Serialize(output, result);
Is there any way to prevent code I don't have from writing to stdout?

Assuming you want to disable third party component output and you have control over the rest of SubApp code you can do following trick: Redirect standard output to null at application bootstrap. When you need to write something to stdout temporary set standard output back to normal, write and set to null again.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace stdio
{
class Program
{
static void Main(string[] args)
{
Console.SetOut(System.IO.TextWriter.Null);
Console.WriteLine("This will go to > null");
WriteOutput("This is written to standard output");
Console.WriteLine("This will also go to > null");
Console.ReadKey();
}
static void WriteOutput(String someString)
{
Console.SetOut(Console.Out);
Stream output = Console.OpenStandardOutput();
StreamWriter sw = new StreamWriter(output);
sw.Write(someString);
sw.Flush();
sw.Close();
output.Close();
Console.SetOut(System.IO.TextWriter.Null);
}
}
}

I've tried this:
StreamWriter sw = new StreamWriter(#"c:\nul");
Console.SetOut(sw);
Console.WriteLine("hello!");
But it throws an exception in new StreamWriter().
The following might work (call it before your external module becomes active):
StreamWriter sw = new StreamWriter(Stream.Null);
Console.SetOut(sw);
A workaround would be to open a real text file and delete it.

Related

C# - While writing into a text file, the ouput file is not created [duplicate]

This question already has answers here:
Easiest way to read from and write to files
(14 answers)
Closed 2 years ago.
Below is the code I have. My issue is that the file.txt is not created at all!
I cannot find the reason. Program should create it. Could you please help me ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WriteToFile
{
class Program
{
static void Main(string[] args)
{
string line = "Please help me to write something!!";
System.IO.StreamWriter file = new System.IO.StreamWriter
(#"C:\Users\jgonc\source\repos\WriteToFile\WriteToFile\bin\Debug\file.txt");
file.Flush();
file.WriteLine(line);
file.Close();
Console.WriteLine("press a key");
Console.ReadKey();
}
}
}
//line you want to write to the document
string line = "Please help me to write something!!";
//path to my documents
string docPath =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
using (StreamWriter sw = new StreamWriter(Path.Combine(docPath, "test.txt")))
{
sw.WriteLine(line);
}
Console.WriteLine("press a key");
Console.ReadKey();
Here I make use of the using keyword. This is extremely useful as any object created in the parameters will automatically be destroyed when the using segment ends which is great because it means you don't need to clutter your code with unnecessary flushes and closes.
Its also important you understand the difference between a flush & a close. Here when the using segment ends dispose is called on streamwriter which in turn calls close, which closes the stream. A flush is simply clearing the buffer.
Check that you the application has permission to write to my documents directory - here
I have changed the path to my documents as the bin folder often changes or is deleted.
Thank you for your support and hints.
I've investigate the permissions topic and it seems it was related to it.
After uninstalling my antivirus it started to work.
below is the final code, to write a couple of strings using StreamWriter.
static void Main(string[] args)
{
string[] lines = {
"Please help me to write something!",
"It's working now, it was related with my antivirus, it was somehow blocking my permissions to the folder",
"Thanks for your support and your hints!!",
};
//string path = #"C:\Users\jgonc\source\repos\WriteToFile\WriteToFile\bin\Debug\file.txt";
string path = #"file.txt";
System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);
System.IO.StreamWriter file = new System.IO.StreamWriter(fs, System.Text.Encoding.ASCII);
if (!File.Exists(path))
{
Console.WriteLine("file was not created");
}
else
{
using (file)
{
foreach (string line in lines) {
file.WriteLine(line);
}
}
}
fs.Close();
Console.WriteLine("Press a Key to End...");
Console.ReadKey();
}
Try :
System.IO.StreamWriter file = new System.IO.StreamWriter
(#"C:\Users\jgonc\source\repos\WriteToFile\WriteToFile\bin\Debug\file.txt", true);
true for append attribute set it false if you want to create file every time.

SSH.NET doesn't process my shell input commands

I'm using SSH.NET to connect to my Raspberry Pi from a Console Application in C#.
I want to send text from my very own stream, writing to it through a StreamWriter.
The problem is that it does nothing. It's like the WriteLine("ls") doesn't produce any effect.
This is the code:
using System;
using System.IO;
using Renci.SshNet;
namespace SSHTest
{
class Program
{
static void Main(string[] args)
{
var ssh = new SshClient("raspberrypi", 22, "pi", "raspberry");
ssh.Connect();
var input = new MemoryStream();
var streamWriter = new StreamWriter(input) { AutoFlush = true };
var stdout = Console.OpenStandardOutput();
var shell = ssh.CreateShell(input, stdout, new MemoryStream());
shell.Start();
streamWriter.WriteLine("ls");
while (true)
{
}
}
}
}
What's the problem?
MemoryStream is not a good class for implementing an input stream.
When you write to MemoryStream, as with most stream implementations, its pointer is moved at the end of the written data.
So when SSH.NET channel tries to read data, it has nothing to read.
You can move the pointer back:
streamWriter.WriteLine("ls");
input.Position = 0;
But the right approach is to use PipeStream from SSH.NET, which has separate read and write pointers (just as a *nix pipe):
var input = new PipeStream();
Another option is to use SshClient.CreateShellStream (ShellStream class), which is designed for task like this. It gives you one Stream interface, that you can both write and read.
See also Is it possible to execute multiple SSH commands from a single login session with SSH.NET?
Though SshClient.CreateShell (SSH "shell" channel) is not the right method for automating command execution. Use "exec" channel. For simple cases, use SshClient.RunCommand. If you want to read a command output continuously, use SshClient.CreateCommand to retrieve the command output stream:
var command = ssh.CreateCommand("ls");
var asyncExecute = command.BeginExecute();
command.OutputStream.CopyTo(Console.OpenStandardOutput());
command.EndExecute(asyncExecute);

redirect printer output to C# application, using redmon

I'm trying to intercept the content from a redirect port (Redmon) to a C# application so I can process it. Right now I'm just trying to figure out how to pass the output into my app.. I thought I could just input it through std input, but its not working. In a coomand line I can pipe text into my application and it works, but if I try to print through a redmon port, my application doesn't seem to take the input. I set up Redmon to let my application handle the output. Here's my code and a screen shot of the printer port settings.
namespace titoprint
{
class Program
{
static void Main()
{
int result;
while ((result = Console.Read()) != -1)
{
Console.WriteLine("{0} = {1} ", result, (char)result);
}
Console.WriteLine("in console");
MessageBox.Show("ok done!");
Console.ReadLine();
}
}
}
`Port settings
I;m only tryint to pass text to the application also. So so the process i'm using is winprint and set to text.
Thanks
You can read like this:
Stream content = Console.OpenStandardInput();
using (BinaryReader standardInputReader = new BinaryReader(content))
{
using (FileStream standardInputFile = new FileStream(standardInputFilename, FileMode.Create, FileAccess.ReadWrite))
{
standardInputReader.BaseStream.CopyTo(standardInputFile);
}
}
Then you can convert to PDF:
String[] ghostScriptArguments = { "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite",String.Format("-sOutputFile={0}", outputFilename), standardInputFilename };

why c# console command not running on java?

Can anyone tell me why this c# console command not running on Java?
I've made a C# console program as given below:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace face
{
class Program
{
public static void Main(string[] args)
{
String path = args[0];
byte[] imageBytes = File.ReadAllBytes(path);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
Bitmap S1 = new Bitmap(image);
Console.WriteLine(S1.GetPixel(2, 10));
}
}
}
When I run Program.exe image.jpg, I get:
Color [A=255, R=128, G=32, B=128]
Then I created a simple Java application to run the Program.exe executable:
class project
{
public static void main(String[] args)
{
String comman="C:\\WINXP\\system32\\Program.exe Sunset.jpg";
try
{
Process process = Runtime.getRuntime().exec(comman);
System.out.println(process.getOutputStream());
} catch (Exception e)
{e.printStackTrace(System.err);}
}
}
When I try to run the Java application, I get the following error:
Program.exe has encountered a problem and needs to close. We are sorry for the inconvenience.
You probably want to change
String comman = "C:\\WINXP\\system32\\Program.exe Sunset.jpg";
to
String[] comman = { "C:\\WINXP\\system32\\Program.exe", "Sunset.jpg" };
As a comment said, it's probably because the C# program can't open the file: you should specify an absolute path for it, since getting the actual working directory to work right can be an unnecessary pain in this situation. Also it wouldn't hurt to catch exceptions in the C# program (for example for the "no arguments" and "file not found" cases).
The C# process is a child process of the java process, and killed automatically then the java VM terminates. Because the process is started asynchronously, that will happen immediately. If you're interested in the output, replace
System.out.println(process.getOutputStream());
with (for instance)
InputStream inputStream = process.getInputStream();
int c;
while ((c = inputStream.read()) >= 0) {
System.out.print((char) c);
}
if not, write
process.getInputStream().close();
process.waitFor();
Apart from what others have said, I don't think that System.out.println(process.getOutputStream()); will output what you want here - namely the output of the executed C# executable.
System.out.println() has no overload for OutputStream, the return type of Process.getOutputStream(). So the System.out.println(Object) overload will be choosen, which will call OutputStream.ToString(), which is not the output of the C# program, but (most likely, bear with me here) the fully qualified typename of the output stream instance.
Check this SO question/answer, for example, for more information.
You need to check path of exe and image file that you have provided. As I check this code and execute it then I get following output
java.io.BufferedOutputStream#c17164
Here I provide you your modified code
public class Test
{
public static void main(String[] args)
{
String path="C:\\C#Sample\\ImageDisplayDemo\\ImageDisplayDemo\\bin\\Debug\\ImageDisplayDemo.exe E:\\Users\\Public\\Pictures\\Sample Pictures\\Desert.jpg";
try
{
Process proc=Runtime.getRuntime().exec(path);
System.out.println(proc.getOutputStream());
}
catch(Exception ex)
{
}
}
}

Create file without opening/locking it?

Does anyone know of a way to (reasonably simple) create a file without actually opening/locking it? In File class, the methods for file creation always return a FileStream. What I want to do is to create a file, rename it (with File.Move) and then use it.
Now I have to:
Create it
Close
Rename
Reopen for use
Maybe you can try using File.WriteAllText Method (String, String)
with the file name and an empty string.
Creates a new file, writes the
specified string to the file, and then
closes the file. If the target file
already exists, it is overwritten.
using (File.Create(...)) { }
While this will briefly open your file (but close it again right away), the code should look quite unobtrusive.
Even if you did some P/Invoke call to a Win32 API function, you would get a file handle. I don't think there's a way to silently create a file without having it open right afterwards.
I think the real issue here is why you go about creating your file in the way you've planned. Creating a file in one place simply to move it to another location doesn't seem very efficient. Is there a particular reason for it?
What about using File.WriteAllBytes method?
// Summary:
// Creates a new file, writes the specified byte array to the file, and then
// closes the file. If the target file already exists, it is overwritten.
Another way is to use FileStream and Close it after creating the file. It will not lock the file. The code will look like:
FileStream fs = new FileStream(filePath, FileMode.Create);
fs.Flush(true);
fs.Close();
You just after this you can rename it as well or move it some other location.
Below is the Test program to test functionality.
using System;
using System.Collections.Generic;
using System.IO; using
System.Linq;
using System.Text;
namespace FileLocking {
class Program
{
static void Main(string[] args)
{
string str = #"C:\Test\TestFileLocking.Processing";
FileIOTest obj = new FileIOTest();
obj.CreateFile(str);
}
}
class FileIOTest
{
internal void CreateFile(string filePath)
{
try
{
//File.Create(filePath);
FileStream fs = new FileStream(filePath, FileMode.Create);
fs.Flush(true);
fs.Close();
TryToAccessFile(filePath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
void TryToAccessFile(string filePath)
{
try
{
string newFile = Path.ChangeExtension(filePath, ".locked");
File.Move(filePath, newFile);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
} }
If you use File.Create(commented in above code) then it will give error saying file is being used by another process.
Incredibly grotty hack, probably the most complicated way to achieve your goal:
use Process class
processInfo = new ProcessStartInfo("cmd.exe", "/C " + Command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
process = process.Start(processInfo);
process.WaitForExit();
where Command would be echo 2>> yourfile.txt

Categories