Search code examples
powershellerror-handlingwindows-servicesnservicebusnservicebus4

Capturing errors when installing NServicebus service in Powershell


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?


Solution

  • 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.