Sometimes you just need to call a console executable. Whether it is legacy code or the only interface for 3rd party software, console applications are still used and still need to be interfaced with. Fortunately, .NET comes with a class built specifically to get that job done. The Process class, located in the Systems.Diagnostics library, can be called to handle console executables and their command line arguments. Below is an example on how to call this useful class:
Process proc = new Process();
// First, specify the executable file name and any command line arguments
proc.StartInfo = new ProcessStartInfo("C:\\temp\\CmdLineProgram.exe",
"-i \"C:\\temp\\InputFile.txt\" -o \"C:\\temp\\OutputFile.txt\"");
// Next, since we want to run this in our program, we don't want the
// shell to execute it nor have it display in an external window.
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
// We also want to get any error or output data that the executable might write out.
// This should capture data normally written out to the console screen.
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
// Now let the executable run. We'll wait here for it to finish process.
// Gather any exit code informationint exitCode = proc.ExitCode;
// And get the output and error messages.
string errorMsg = string.Empty;
using (StreamReader reader = proc.StandardError)
errorMsg = reader.ReadToEnd();
}string outMsg = string.Empty;
using (StreamReader reader = proc.StandardOutput)
outMsg = reader.ReadToEnd();
Hopefully this small sample will help out with making calls to console applications. Regarding retrieval of exit codes, output and error messages, not all console applications like to output them to the same place. Sometimes all output messages actually go to the error message, so you may need to look there. Some trial and error may be necessary, so make sure to test out the code to find what works and what doesn’t.
In the System.Data.SqlClient namespace, SqlConnection and SqlCommand are two examples of managed types that use unmanaged resources down in the COM layer of the run-time. Microsoft says that all of these types must implement the IDisposable interface.
Recently, while working on a project for ImageSource, I ran into a bit of problem that pretty much had me stumped. I had written a .NET library to integrate with a 3rd party COM dll. The code looked correct, it passed all of its test cases and ran just fine when compiled in Debug mode. I created a test application to use this library and stress test it. Everything checked out.
Then I compiled it for Release and obfuscated it. Suddenly it did not run fine anymore. The test application would consistently give me errors of varying severity. Everything from Automation error The server threw an exception to The remote server machine does not exist or is unavailable.
An always unwelcome message.
I could get various errors depending on my input parameters, but they didn’t always occur at the same time. Sometimes I would get a COM exception after 10 iterations of a loop, other times it would be 20.
At first, I thought the issue was that the code was obfuscated. I’ve run into some small bugs in the past when obfuscating code, and thought this was no different. However, testing a non-obfuscated Release build of the code produced the same problem. Only switching back to the Debug build fixed the issue. Lots of head banging ensued.
After trying to figure out error messages that seemed to have little rhyme or reason, I finally went back and looked at sample code provided by the 3rd party. After testing their code and finding that it run fine in Release mode, I had to figure out what this code was doing that mine was not.
Their code called a logout method in the API and mine didn’t.
Looking at my own code, I had completely missed making that call and it made all of the difference in the world. My code was staying logged into the server, or at least causing problems server-side because I wasn’t disconnecting.
One added line later and the Release build of my library was working perfectly. In fact, even the obfuscated version worked without a problem. All of that grief and headache caused by one line of missing code.
So I guess the moral of this story is this: Make sure that you close you connections, you release your objects, that you make sure you clean up your mess. Because if you don’t, it could come back to bite down the road. Also, don’t be ashamed to go back and look at sample code when you’re stuck. Sometimes the answer is right in front of you.
As a developer, I install and uninstall all sort of programs on my system so I am not surprised when some weird and random error message popped up. I ran into the following error dialog today when I was writing some .NET integration code with EMC AppXtender.
Have you ever been writing an application and needed to retrieve or edit the properties of a Microsoft Office document? Did the thought of having to write code to perform Word or Excel automation send chills down your spine? Were you worried that your documents’ precious metadata would forever be trapped behind the taunting shield of the Windows Explorer property window?