1

What I have:

  • ASP.NET Core 2.1 Web Application (self-hosted deployment, not using IIS).
  • When I pass --register-service or --unregister-service as command line arguments to my app, it (un)registers itself as a Windows Service and then exits.
  • MSI installer (WiX Toolset 3.11) which registers the web application as a Windows Service by using the above command line argument in a Custom Action.
  • When doing an upgrade from version 1 to version 2 of my application, the MSI installer successfully performs the following steps:
    • Unregister version 1 as Windows Service
    • Remove binaries of version 1
    • Copy binaries of version 2
    • Register and (attempt to) start version 2 as Windows Service

Problem:

The newly installed version 2 does not start properly because apparently the port is still blocked:

System.IO.IOException: Failed to bind to address https://[::]:5001: address already in use. ---> Microsoft.AspNetCore.Connections.AddressInUseException: Only one usage of each socket address (protocol/network address/port) is normally permitted ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted

Interestingly when any of these two versions is installed, I can stop and start the Windows Service without any issues. The problem with the blocked port seems to occur specifically in the context of an MSI upgrade.

What I tried:

Once the MSI installer is finished, I can just restart the newly installed service manually and it runs fine. So it looks like it just takes some more time for the port to become available. So what I tried is some kind of a re-try mechanism, along these lines (simplified):

IWebHost host = null;

Start:
host?.Dispose();

host = CreateWebHost();
try
{
    await host.RunAsync(ct);
}
catch (IOException ex) when (ex.InnerException is AddressInUseException)
{
    await Task.Delay(TimeSpan.FromSeconds(5), ct);
    goto Start;
}

However, then I get the following exception in some service where I try to use an injected IServiceScopeFactory when doing the first re-try:

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'IServiceProvider'.

So it looks like even I'm creating a completely new IWebHost for retrying, the DI container still seems to be in a bad state from the first try.

Questions:

  1. What could be the reason for this blocked port, apparently only in the context of an MSI update? Could it be that the Windows Installer itself is not releasing the port? How to solve or workaround this?
  2. With regards to the workaround I tried: Why do I get that ObjectDisposedException? Is there a better way to re-try while the port is still blocked?
Robert Hegner
  • 9,014
  • 7
  • 62
  • 98
  • Can't see what tool you have used to create that MSI? Visual Studio Installer Project? – Stein Åsmul Jul 18 '19 at 16:45
  • I updated my question with some more details about the MSI installer. – Robert Hegner Jul 18 '19 at 18:29
  • Before looking too much at this, I would assume you could avoid this by eliminating the custom actions and instead use the built-in MSI mechanisms to start & stop and to install & uninstall services. Rather than rewriting everything, I'll direct you to [this previous answer](https://stackoverflow.com/a/52095690/129130). The sample markup should be all you need. The resulting MSI will have tables with settings that will be used to start, stop, install and uninstall the service. Worth a try. – Stein Åsmul Jul 18 '19 at 23:18
  • Thanks for this suggestion. Note that the previous version is already released, so I cannot change the way the old version gets uninstalled. I can only solve/workaround the problem on the installing side – Robert Hegner Jul 19 '19 at 07:22
  • Didn't read it properly, but [maybe have a look here](https://stackoverflow.com/questions/52649979/failed-to-bind-to-address-already-in-use-error-with-visual-studio-mac-api). [Search](https://www.google.com/search?ei=RHkxXZnRLMnRwQLMrYGQBg&q=Failed+to+bind+to+address+address+already+in+use) (maybe read comments to third link?). You are using the `.UseUrls` construct already? I should not try to answer this, I don't know IIS at all anymore :-). – Stein Åsmul Jul 19 '19 at 08:58
  • My web application is self-hosted (Kestrel), so not using IIS. I updated my question to reflect that. – Robert Hegner Jul 22 '19 at 13:19

0 Answers0