We've created a new hosted service using .NET Core 3.1 and the WorkerService template.
We want to run this service as a "Windows Service".
If I run the program manually using a Powershell shell, it runs fine with no problems.
So I then added it as a windows service. To do this, I followed these steps:
Added the Microsoft.Extensions.Hosting.WindowsServices package
Added the following to CreateHostBuilder:
public static IHostBuilder CreateHostBuilder(Serilog.ILogger logger, string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService() // <-- added this line
.ConfigureAppConfiguration(configurationBuilder =>
{
configurationBuilder.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true);
})
Published it to a folder (zipped it and copied to server).
Added it as a service:
PS C:\Windows\system32> sc.exe create MyService binpath= "C:\Program Files\Services\MyService.exe"
5. Opened the Services snap-in and started the service.
The snap-in shows that it has a status of "running".
However, the program does not seem to actually do anything. It is not logging anything, including the most basic "Starting up" log message.
I even added a Seq sink on the off-chance that there was an IO problem preventing it from writing to a file. But nothing.
Can anyone identify what I am doing wrong?
As per comment on issue 36065, when a .NET Core 3.1 worker service runs as a windows service "Directory.GetCurrentDirectory() will point to %WINDIR%\system32". Therefore to get the current directory, you could use some reflection and something like:
public static IHostBuilder CreateHostBuilder(Serilog.ILogger logger, string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService() // <-- added this line
.ConfigureAppConfiguration(configurationBuilder =>
{
configurationBuilder.SetBasePath(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))
.AddJsonFile("appsettings.json", optional: true);
});
Worth noting, according to this comment, it's resolved in .NET 5.0
Related
In Program.cs, I use this code
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("http://0.0.0.0:5100");
}).UseWindowsService();
In appsettings.json, I use this connection string because I'd like to read/write my old foxpro dbf file.
"ConnectionStrings": {
"MyConn": "Provider=VFPOLEDB.1;Data Source=c:\\datafolder\\programfolder"
},
My project run fine on Windows 10 x64 but when I deploy my project to Windows Server 2008 x64 or Windows Server 2019 x64 as a Windows Service, and run in browser like http://localhost:5100/api/listdoc
Browser return this message.
This page isn’t working localhost is currently unable to handle this
request. HTTP ERROR 500
And when I look in Event Viewer on Server, It show me like this.
Connection id "0HMISIA4G5VUU", Request id "0HMISIA4G5VUU:00000001": An
unhandled exception was thrown by the application.
Exception: System.InvalidOperationException: The 'VFPOLEDB.1'
provider is not registered on the local machine.
I've also setup VFPOLEDBSetup.msi and VFPODBC.msi on that system. Please advice me to solve this issue. Thanks in advance.
I am new to programming, and I was able to solve most of the issues all by myself. But this issue goes over my head.
I am using Visual Studio to run my app locally. When I click on "IIS Express" within VS to run the app, the app is opening in a browser with url http://localhost:1234/ and serving static files.
However when I use IIS to host my app, like when I type myapp.com in my browser, I am seeing website in plain text. And no static files (css, js) are being served.
Not sure what is causing the issue. I googled for long time and read lot of posts, but most of them are asking to check if IIS has static role service turned or suggesting to use app.UseStaticFiles() within startup.cs file. Which in my case is done.
program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDefaultFiles();
app.UseStaticFiles();
}
Any help is much appreciated.
I didnt know that when we publish it to "files and folder" from Visual studio, any changes that we make in Visual studio will not go through to published folder. Because of this reason "app.UseStaticFiles();" command (that I wrote after publishing) is not passed on to published folder. I had to delete the published folder and republish to make everything work fine.
I have an aspnetcore 2.1 app running on azure.
I now want to view logging information to debug an issue that occurs only on Azure.
In the app, an ILogger<> is injected into the class and used:
this._logger.LogInformation("constructor**********************************************");
If I run the app in VS, I can see the output in both the debug output window, as well as the asp.net core web server output window.
I then publish and go on Azure and enable the Log Stream and view it. I do see information appearing in the log stream, but it is just the request information from IIS. I don't see any other log messages.
Is there anything else I need to do to see the logging information on Azure?
You can use Microsoft.Extensions.Logging.AzureAppServices. The package describes itself as:
Logger implementation to support Azure App Services 'Diagnostics logs' and 'Log stream' features.
Once you've installed the package, you'll need to update the logger configuration to use this new provider, which is usually done in Program.cs, like this:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(loggingBuilder =>
{
loggingBuilder.AddAzureWebAppDiagnostics();
})
...
.UseStartup<Startup>();
You need to configure Application Insights with your application to see the logs generated.
You can read the steps from Enable diagnostics logging for web apps in Azure App Service
You need to install and configure Azure Application Insights for your project.
By configuring the Instrument Key in your application you can send all the kinds of logs from your application to Application Insights.
Install the below Nuget
Microsoft.ApplicationInsights.AspNetCore 2.2.0 NuGet packages
Configure the Application Insights in you asp.net core application
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
// Change to file post adding Application Insights Telemetry:
.UseApplicationInsights()
//
.UseStartup<Startup>()
.Build();
}
See this step by step instruction on how to configure application insights into your asp.net core
I have an ASP.NET Core Api where I use the appsettings.{environmentname}.json configuration files. Then I also have the appropriate launchSettings.json file with the different environment options so I can run with any specific environment settings file.
In the Startup.cs, we have a conditional setting where if we are in a non-prod environment, then we use a specific set of Jwt authentication (just has some validating checks turned off), then in prod, we load a different version that has all of the checks to turn on.
On my localhost, this works great where environment.IsDevelopment() returns true, while environment.IsProduction() returns false. Great!
But, when I run this through our build process and deploy to our test environment, the environment.IsDevelopment() now returns false.
I have added in the option in the Program.cs file to add the ConfigurationBuilder so I can pass variables to my build process, which looks like this:
dotnet restore
dotnet build --environment "Development"
dotnet publish -o ..\Artifacts
I'll post the relevant files, and the associated code for more info...
Program.cs
public static IWebHost BuildWebHost(string[] args)
{
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
return WebHost.CreateDefaultBuilder(args)
.UseConfiguration(config)
.UseStartup<Startup>()
.UseNLog()
.Build();
}
Startup.cs (ConfigureServices method)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
// removed code not relevant...
// options.TokenValidationParameters = Environment.IsProduction()
// options.TokenValidationParameters = Environment.IsEnvironment("Prod")
options.TokenValidationParameters = Environment.IsDevelopment()
? devTokenValidationParameters
: prodTokenValidationParameters;
// options.TokenValidationParameters = devTokenValidationParameters;
});
Why are the helper environment.Is{EnvironmentName}() checks not working here?
The environment name is runtime concept rather than a compile (or build) time concept. This means that when building (or publishing) an application the environment is not yet known and setting is has no effect. Your code is not running when you publish the application.
You can control the environment name when running the application e.g. via an argument of dotnet run:
dotnet run --environment=Production
Or using a known environment variable ASPNETCORE_ENVIRONMENT. For example by executing this at the command line:
set ASPNETCORE_ENVIRONMENT=Production
This variable might also be set using the launchSettings.json file for debugging purposes. This file is generated when creating a new project using Visual Studio or dotnet new.
The default environment for an application is Production. Please refer to the documentation for more info about this topic.
I am trying to override the server url manually with a hosting.json file, however the url never get's used. I am on .net core 2.0.
hosting.json:
{
"urls": "http://localhost:5000"
}
Program.cs:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
IConfigurationRoot config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.AddCommandLine(args)
.Build();
return WebHost.CreateDefaultBuilder(args)
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
}
}
Visual Studio gives you two profiles to run application:
IIS Express, which fairly obviously runs the application using IIS Express and
WebApplication2 (or any given name of your app), the name of the web project, which runs the application using dotnet run using Kastrel instead of IIS.
You can try switching and running application from the second profile (it should pick up hosting.config).
If you want to run app on IIS you can change launchSettings.json that is located under project properties
Also, you can find more details how to configure urls here.