I am aware that this may on first glance look like a question you have seen before: Knowing when an external process' window shows
But this is slightly different.
I have an C# asp.net web application, for helping people create an installer for their programs. (The developers here are mostly mechanical engineers scripting equations in some calculation tools, they are not software people, so we don't want them spending time learning wix, debugging the installers, maintaing GUID's between releases, and so on..)
The serverside will be running the console application "heat.exe" (a tool that is shipped with the wix tools), to harvest information on how to register dll's etc., if and only if they have a dll in their repository..
I do it like this:
public int runHeat(string filePath, string outputFile, ref string response)
{
response += "run heat.exe to harvest file data" + '\r' + '\n';
string args = "file " + '"' + filePath + '"' + " -srd -out" + '"' + outputFile + '"';
string command = Path.Combine(WixBinariesPath, "heat.exe");
string workPath = Path.GetDirectoryName(filePath);
StringBuilder outputBuilder;
ProcessStartInfo processStartInfo;
Process process;
outputBuilder = new StringBuilder();
processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.WorkingDirectory = workPath;
processStartInfo.Arguments = args;
processStartInfo.FileName = command;
processStartInfo.ErrorDialog = false;
//create the process handler
process = new Process();
process.StartInfo = processStartInfo;
// enable raising events because Process does not raise events by default
process.EnableRaisingEvents = true;
// attach the event handler for OutputDataReceived before starting the process
process.OutputDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
// append the new data to the data already read-in
outputBuilder.AppendLine(e.Data);
}
);
// start the process
// then begin asynchronously reading the output
// then wait for the process to exit
// then cancel asynchronously reading the output
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
// use the output
response += outputBuilder.ToString();
if (process.ExitCode != 0)
response += '\r' + '\n' + "heat.exe exited with code: " + process.ExitCode;
process.CancelOutputRead();
return process.ExitCode;
}
I thought this worked.. It passed tests, it's been running for a while without problems, and then suddenly, a developer called, that the webtool I made, no longer produces wix xml for him..
When I logged into the server, I found this dialog:
and then clicked [OK] - the web application then continued, and produced the xml, and stuff worked..
I have now found the dll that, makes heat throw this error. It doesn't really need registering (typical right?). So I could probably just write a timeout thing, to kill heat.exe if it takes to long, and thus unlock the waiting script, (and basicly fix the issue untill it happens again with a dll that actually needs registering) But that is not really detecting the error, that is just detecting that stuff takes time...
On this error, I would like to continue the script, but present a warning to the user, that heat.exe failed to run on that particular file. But to do this I need my asp.net application to know that this error was invoked, and dispose it, so that the script can continue..
how the *? do I get information that this runtime error occurred, so I can handle it from the server script?
Have you tried using the -sreg command line option to heat?
I now have, and as a result, heat.exe no longer chrashes, but this is not a solution, as heat also avoids harvesting the registry information that I need for autoregistering the dll's shipped with the code in question.