views:

48

answers:

3

Hello Guys!

I'm using the native windows application spamc.exe (SpamAssassin - sawin32) from command line as follows:

C:\SpamAssassin\spamc.exe -R < C:\email.eml

Now I'd like to call this process from C#:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.FileName = @"C:\SpamAssassin\spamc.exe";
p.StartInfo.Arguments = @"-R";
p.Start();

p.StandardInput.Write(@"C:\email.eml");
p.StandardInput.Close();
Console.Write(p.StandardOutput.ReadToEnd());
p.WaitForExit();
p.Close();

The above code just passes the filename as string to spamc.exe (not the content of the file). However, this one works:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.FileName = @"C:\SpamAssassin\spamc.exe";
p.StartInfo.Arguments = @"-R";
p.Start();

StreamReader sr = new StreamReader(@"C:\email.eml");
string msg = sr.ReadToEnd();
sr.Close();

p.StandardInput.Write(msg);
p.StandardInput.Close();
Console.Write(p.StandardOutput.ReadToEnd());
p.WaitForExit();
p.Close();

Could someone point me out why it's working if I read the file and pass the content to spamc, but doesn't work if I just pass the filename as I'd do in windows command line?

+2  A: 

In the first example you are passing a string that represents the file not the file.

kenny
OK, so what is the correct way to pass the file? Are there any other solutions than the second example?
Cosmo
Other than changing the program to open the file itself, your second solution is a decent method.
kenny
+1  A: 

Your first code sample is the equivalent of directing input from a file containing the line C:\email.eml:

echo C:\email.eml > inputfile
C:\SpamAssassin\spamc.exe -R < inputfile

Your second code sample passes the content of C:\email.eml to spamc.

Phil Ross
+3  A: 

It's cause on the command line the < is a little magic parameter. It just does a little bit more, then you maybe expect. In fact it opens the file and put its content into the standard input of the process. So that's the same you must do manually when using the Process class.

As you already showed in your second example you have to use a StreamReader to get the content of the file and put it into the StandardInput. Just to make it a little more robust you can maybe use this little code snippet:

using (var streamReader = new StreamReader(fileInfo.FullName))
{
    process.StandardInput.Write(streamReader.ReadToEnd());
    process.StandardInput.Flush();
}
Oliver