Description
Description
Using the library Microsoft.Extensions.Hosting.WindowsServices
and a builder like the following:
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseWindowsService(options => options.ServiceName = "foobar")
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Agent>();
});
}
When executing as a service in a Windows Container the following can be observed:
System event logs:
# Get-EventLog -LogName Application -Newest 10 | %{ $_.Message }
A timeout was reached (30000 milliseconds) while waiting for the foobar...
A timeout was reached (30000 milliseconds) while waiting for the foobar...
A timeout was reached (30000 milliseconds) while waiting for the foobar...
Application event logs:
# Get-EventLog -LogName Application -Newest 10 | %{ $_.Message }
Windows Management Instrumentation Service subsystems initialized successfully
Category: Microsoft.Extensions.Hosting.Internal.Host
EventId: 2
Hosting started
Category: Microsoft.Hosting.Lifetime
EventId: 0
Content root path: C:\Windows\system32
Category: Microsoft.Hosting.Lifetime
EventId: 0
Hosting environment: Production
Category: Microsoft.Hosting.Lifetime
EventId: 0
Application started. Press Ctrl+C to shut down.
Category: Microsoft.Extensions.Hosting.Internal.Host
EventId: 1
Hosting starting
Category: Microsoft.Extensions.Hosting.Internal.Host
EventId: 2
Hosting started
Category: Microsoft.Hosting.Lifetime
EventId: 0
Content root path: C:\Windows\system32
Category: Microsoft.Hosting.Lifetime
EventId: 0
Hosting environment: Production
Category: Microsoft.Hosting.Lifetime
EventId: 0
Application started. Press Ctrl+C to shut down.
It appears the the "host" (that the right name?) does not detect it's running as a service. So the app defaults to running as a console app.
Digging deeper, there's a check for "am I a service?" in Microsoft.Extensions.Hosting.WindowsServices.IsWindowsService()
.
Looking at what this checks:
- Is Windows? Yes.
- Is there a parent process? Yes.
- Is this process named
services
? Yes. - Is this process executing from session
0
? No?!?
# pslist.exe -accepteula -t
Name Pid Pri Thd Hnd VM WS Priv
Idle 0 0 2 0 8 8 60
System 4 8 88 3565 3696 144 160
wininit 276 13 3 167 4194303 7276 1640
services 316 9 5 225 4194303 6832 2348
foobar 2908 8 10 241 4194303 25380 12688
# Get-Process -id 316 | select name,SessionId
Name SessionId
---- ---------
services 1
Apparently services
doesn't have to run under session 0?
Other information
While "why are running an app in a Windows Container as a Windows Service? Don't do that." would be a completely valid answer.... We are using Windows Containers to provide short lived sandboxes for integration tests - in this case - testing a Wix installer, installing a .NET 5 based Windows Service (self-contained mode). It would be nice if we could continue doing so with .NET 5.
We were historically using TopShelf under .NET Framework, but we migrated to .NET 5. TopShelf does not perform this session 0 check, only the services
name check: https://github.com/Topshelf/Topshelf/blob/03bde8963da8c057ffc6df07ef9600ffdf6047c1/src/Topshelf/Runtime/DotNetCore/DotNetCoreHostEnvironment.cs#L57-L80
Therefore, I propose removing that session id check going forward.