Search code examples
c#windows-servicesasp.net-core-webapi

Why does my Web App run fine in debug but not when it is a Windows Service?


I have a console app that I install as a Windows Service using the Topshelf extension. I thought I should give it a UI so I changed the sdk in the.csproj from

Project Sdk="Microsoft.NET.Sdk"

to

Project Sdk="Microsoft.NET.Sdk.Web"

I then copied code and folders (wwwroot, Controllers etc) from a ASPNET Core WebApp project. I added the following code to the Start method to run the WebApplication.

 var builder = WebApplication.CreateBuilder(args);

 // Add services to the container.
 builder.Services.AddControllersWithViews();

var app = builder.Build();

 // Configure the HTTP request pipeline.
 if (!app.Environment.IsDevelopment())
 {
     app.UseExceptionHandler("/Home/Error");
     // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
     app.UseHsts();
 }

 app.UseHttpsRedirection();
 app.UseStaticFiles();

 app.UseRouting();

 app.UseAuthorization();

 app.MapControllerRoute(
     name: "default",
     pattern: "{controller=Home}/{action=Index}/{id?}");

 app.Start(); //NOTE use of Start and not Run.  Because Run blocks.

I then ran the solution in Debug. Everything works fine. The web page launches and my old console app does it thing (which is basically pinging external websites to check my ISP provider has not dropped my line, again).

However, when I run the Topshelf command to install the exe as a Windows Service and start the service, the Console code runs but the Web part is not available on the expected URLs as set in launchSettings.json.

Is there some setting I should be looking at? Is this a thing that is possible to do?


Solution

  • In the Program.cs file, you can according the launchSettings.json file to configure the listen port for Kestrel.

    builder.WebHost.ConfigureKestrel(serverOptions =>
    {
        serverOptions.ListenAnyIP(42198); // http
        serverOptions.ListenAnyIP(5005); // http
    }); 
    var app = builder.Build(); 
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    } 
    //app.UseHttpsRedirection();
    

    The launchSettings.json file:

    {
      "$schema": "http://json.schemastore.org/launchsettings.json",
      "iisSettings": {
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iisExpress": {
          "applicationUrl": "http://localhost:42198",
          "sslPort": 44337
        }
      },
      "profiles": {
        "http": {
          "commandName": "Project",
          "dotnetRunMessages": true,
          "launchBrowser": true,
          "applicationUrl": "http://localhost:5005",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
        "https": {
          "commandName": "Project",
          "dotnetRunMessages": true,
          "launchBrowser": true,
          "applicationUrl": "https://localhost:7199;http://localhost:5005",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
        "IIS Express": {
          "commandName": "IISExpress",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        }
      }
    }
    

    Then, after publishing the application, use the following command to create the window services.

    sc.exe create MyTestService1 binPath= "{EXE FILE PATH (for example: E:\Test\Test Windoes Services\service1\ConsoleServices.exe)}"
    

    After that we can access the web page via the "http://localhost:42198/" or "http://localhost:5005/"

    enter image description here

    In my above sample, I'm using the Local System Account (right click the service and select the Properties).

    enter image description here

    If you still meet the site can't be reached error, you can change the account to your admin account and their credentials as below and then restart the service.

    enter image description here