By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,213 Members | 1,105 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,213 IT Pros & Developers. It's quick & easy.

Need to create a wrapper to execute a program

P: n/a
Hello,

I'm trying to create a wrapper for a program. I want to execute
program 'X' by running program 'Y', such that 'Y' appears to function
pretty much like 'X' both in the way command line options are handled
and the way input, output and error messages are reported. Program 'X'
is a console application.

I had it pretty well figured out, I thought, until I ran into a case
where program X spit out ZIP code. In other words, I was reading
Process.StandardOutput.ReadLine() and writing to Console.WriteLine().
These don't handle binary output very well.

So I can read X's output using
Process.StandardOutput.BaseStream.ReadByte() but I can't find the
right method to write binary to Y's standard output. How do I convert
Console.Out to a StreamWriter? I want this to work efficiently, too.

Here's the program so far. Thanks for any suggestions.

using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace TigerHeron.CoreLib
{
public class ProgramExecute
{
public const int NONE = 0;
public const int REDIRECT_IO = 1;
private Process process;

public ProgramExecute(string[] args) : this(args, NONE)
{
}

public ProgramExecute(string[] args, int flags)
{
if (args.Length < 1) {
throw new ArgumentException("The array must have at least one
argument", "args");
}

process = new Process();
String program = args[0];

string newArgs = "";
for (int i = 1; i < args.Length; i++) {
newArgs += "\"" + args[i] + "\" ";
}
process.StartInfo.FileName = program;
process.StartInfo.Arguments = newArgs;

if ((flags & REDIRECT_IO) != 0) {
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
}

process.StartInfo.Verb = "Open";
process.StartInfo.UseShellExecute = (flags & REDIRECT_IO) == 0;
process.StartInfo.ErrorDialog = (flags & REDIRECT_IO) == 0;
process.StartInfo.CreateNoWindow = true;
process.Start();

if ((flags & REDIRECT_IO) != 0) {
new Thread(new ThreadStart(this.readStdin)).Start();
new Thread(new ThreadStart(this.readStdout)).Start();
new Thread(new ThreadStart(this.readStderr)).Start();
process.WaitForExit();
Environment.Exit(process.ExitCode);
}
}

private void readStdin()
{
try {
string line;
while ((line = Console.In.ReadLine()) != null) {
process.StandardInput.WriteLine(line);
}
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
}

private void readStdout()
{
try {
int b;
while ((b = process.StandardOutput.BaseStream.ReadByte()) != -1) {
Console.Write((char)b); // This doesn't work
}
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
}

private void readStderr()
{
try {
string line;
while ((line = process.StandardError.ReadLine()) != null) {
Console.Error.WriteLine(line);
}
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
}
}
}

May 14 '07 #1
Share this Question
Share on Google+
1 Reply


P: n/a
On May 14, 6:37 am, Tony Freixas <tfrei...@gmail.comwrote:
Hello,

I'm trying to create a wrapper for a program. I want to execute
program 'X' by running program 'Y', such that 'Y' appears to function
pretty much like 'X' both in the way command line options are handled
and the way input, output and error messages are reported. Program 'X'
is a console application.

I had it pretty well figured out, I thought, until I ran into a case
where program X spit out ZIP code. In other words, I was reading
Process.StandardOutput.ReadLine() and writing to Console.WriteLine().
These don't handle binary output very well.

So I can read X's output using
Process.StandardOutput.BaseStream.ReadByte() but I can't find the
right method to write binary to Y's standard output. How do I convert
Console.Out to a StreamWriter? I want this to work efficiently, too.

Here's the program so far. Thanks for any suggestions.

using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace TigerHeron.CoreLib
{
public class ProgramExecute
{
public const int NONE = 0;
public const int REDIRECT_IO = 1;
private Process process;

public ProgramExecute(string[] args) : this(args, NONE)
{
}

public ProgramExecute(string[] args, int flags)
{
if (args.Length < 1) {
throw new ArgumentException("The array must have at least one
argument", "args");
}

process = new Process();
String program = args[0];

string newArgs = "";
for (int i = 1; i < args.Length; i++) {
newArgs += "\"" + args[i] + "\" ";
}
process.StartInfo.FileName = program;
process.StartInfo.Arguments = newArgs;

if ((flags & REDIRECT_IO) != 0) {
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
}

process.StartInfo.Verb = "Open";
process.StartInfo.UseShellExecute = (flags & REDIRECT_IO) == 0;
process.StartInfo.ErrorDialog = (flags & REDIRECT_IO) == 0;
process.StartInfo.CreateNoWindow = true;
process.Start();

if ((flags & REDIRECT_IO) != 0) {
new Thread(new ThreadStart(this.readStdin)).Start();
new Thread(new ThreadStart(this.readStdout)).Start();
new Thread(new ThreadStart(this.readStderr)).Start();
process.WaitForExit();
Environment.Exit(process.ExitCode);
}
}

private void readStdin()
{
try {
string line;
while ((line = Console.In.ReadLine()) != null) {
process.StandardInput.WriteLine(line);
}
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
}

private void readStdout()
{
try {
int b;
while ((b = process.StandardOutput.BaseStream.ReadByte()) != -1) {
Console.Write((char)b); // This doesn't work
}
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
}

private void readStderr()
{
try {
string line;
while ((line = process.StandardError.ReadLine()) != null) {
Console.Error.WriteLine(line);
}
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
}
}
}

}
Dear Tony,

stdout/stdin can't output or input binary data. It's purpose is to
output/input charecters, depending on encoding settings.

Using BaseStream is not a good way since the StandardOutput is a
wrapper to the base stream. You can't be sure the wrapper doe's
exactly what the base stream does.
If you need to redirect binary data, you should use other methods to
achieve this purpose.

May 14 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.