So, I have a powershell script to install an NServiceBus service as a Windows Service.
Invoke-Expression "$fullNsbHostPath $arguments"
For completeness, I've tried both Invoke-Expression
and Start-Process
:
Start-Process -Wait -NoNewWindow -FilePath $fullNsbHostPath -ArgumentList $arguments -RedirectStandardOutput $tempFileName -ErrorVariable $errvar
It fires up the installer just fine, which under certain circumstances reports an exception For example:
Failed to execute installers: System.Data.SqlClient.SqlException
(0x80131904): A connection was successfully established with the
server, but then an error occurred during the login process.
(provider: Shared Memory Provider, error: 0 - No process is on the
other end of the pipe.) ---> System.ComponentModel.Win32Exception
(0x80004005): No process is on the other end of the pipe ... Error
....
Number:233,State:0,Class:20
I'm happy with this. I expect the exception. However, the process itself gives no indication that it's failed. Indeed, the Powershell script itself completes successfully.
I could parse the output text for an error code or maybe some 'exception' text, but this seems lamentably unsatisfactory.
I don't think this is a Powershell issue. When I run it simply through the command line and examine %errorlevel%
I get 0
. Moreover, several other example online scripts that do the same also omit any error propagation.
Any suggestions?
To elaborate on my comment to the OP, when you use NServiceBus.Host.exe to install a Windows service, it eventually calls WindowsInstaller.RunInstall
from the NServiceBus.Hosting.Windows.Installers
namespace to perform the installation:
private static void RunInstall()
{
Console.WriteLine("Executing the NServiceBus installers");
try
{
WindowsInstaller.host.Install();
}
catch (Exception ex)
{
Console.WriteLine("Failed to execute installers: " + ex);
}
}
As you can see, this method catches all exceptions from the installation process and writes them to the console standard output stream. It doesn't write to the error output stream (Console.Error
) or set the exit code (Environment.ExitCode
), so your only option is to parse the standard output from the application.