gRPC as Windows Service - c#

I am experimenting with gRpc and have it running. I am using .net core 3.1. C# . I am now attempting to install it as a windows service. The machine is Win 10 Pro x64 .
I added the line as instructed to run it as a windows service...
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
//https://learn.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/self-hosted
.UseWindowsService() // Enable running as a Windows service
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
I publish to a folder (I never have used publish before) and voila... there is the publish folder. I go to that folder and run (AS ADMINISTRATOR) installutil. Yes it found the utility as i used the full path. That path is
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe"
Is this correct version to run for .net core? Does that matter?
So I run installutil {full-path-to}\grpcservice1.exe
I get...
Exception occurred while initializing the installation:
System.BadImageFormatException: Could not load file or assembly
'file:///....\GrpcService1\GrpcService1\bin\Debug\netcoreapp3.1\publish\GrpcService1.exe'
or one of its dependencies. The module was expected to contain an
assembly manifest..
I can't figure out what I am doing wrong....
Suggestions? I just following the example.
TIA

installutil.exe looks for an Installer class marked with the RunInstallerAttribute set to true. It only works for Windows Services written with .NET Framework.
In the case of .NET Core, I'd recommend publishing your application and registering a new service using sc create/New-Service as you would in the case of any other executable.
There are also detailed docs in the .NET Core documentation in case you needed something more detailed.

Related

ASP.NET Core on Azure Web Apps, adding Azure Web App Diagnostics throws FileNotFoundException on startup

We deploy a ASP.NET Core 3.0 web application to Azure Web Apps. In order to get log messages we want to use Azure Web Apps diagnostics. We add the logging provider in program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
However, on application startup, a FileNotFoundException is logged to stdout (for details and a stack trace see below) and the application fails to start (Status code 500.30).
We have taken the following steps to find the reason, but up to now, we were not successful:
We have used Kudu and asserted that the directory exists. The settings.json file in the directory mimics the settings we have set in log configuration.
In addition, we have added a call to Directory.Exists in program.cs to verify that the directory exists. This also returned true.
We have recreated the Azure Web App with the same name in the same app service plan with the same settings; the application fails to start.
In a newly created ASP.NET Core 3.0 project, we set up logging successfully, even after we mirrored some specifics of the larger solution; we verified that the following characteristics do not keep the test app from logging successfully:
Run from package was not set at first (we deployed the test app directly from Visual Studio), but we created a build process that deploys a package with Run from package set. So the general build and release process is identical.
We copied the web.config from the larger project (that was adjusted to save the log messages to stdout)
We copied the contents of program.cs between the projects, so that the code that creates the web host is identical.
Does anyone know a reason for this behavior or some other steps that we can use to get more details?
Exception details
Unhandled exception. System.IO.FileNotFoundException: Error reading
the D:\home\site\diagnostics\ directory.
at System.IO.FileSystemWatcher.StartRaisingEvents()
at System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()
at System.IO.FileSystemWatcher.set_EnableRaisingEvents(Boolean
value)
at
Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.TryEnableFileSystemWatcher()
at
Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(String
filter)
at
Microsoft.Extensions.FileProviders.PhysicalFileProvider.Watch(String
filter)
at
Microsoft.Extensions.Configuration.FileConfigurationProvider.<.ctor>b__1_0()
at
Microsoft.Extensions.Primitives.ChangeToken.ChangeTokenRegistration1..ctor(Func1
changeTokenProducer, Action`1 changeTokenConsumer, TState state)
at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1
changeTokenProducer, Action changeTokenConsumer)
at
Microsoft.Extensions.Configuration.FileConfigurationProvider..ctor(FileConfigurationSource
source)
at
Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder
builder)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at
Microsoft.Extensions.Logging.AzureAppServices.SiteConfigurationProvider.GetAzureLoggingConfiguration(IWebAppContext
context)
at
Microsoft.Extensions.Logging.AzureAppServicesLoggerFactoryExtensions.AddAzureWebAppDiagnostics(ILoggingBuilder
builder, IWebAppContext context)
at
Microsoft.Extensions.Logging.AzureAppServicesLoggerFactoryExtensions.AddAzureWebAppDiagnostics(ILoggingBuilder
builder)
at sevacation.Program.<>c.b__1_0(ILoggingBuilder
logging) in D:\a\1\s\sevacation\Program.cs:line 22
at
Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.<>c__DisplayClass5_0.b__1(ILoggingBuilder
builder)
at
Microsoft.Extensions.DependencyInjection.LoggingServiceCollectionExtensions.AddLogging(IServiceCollection
services, Action`1 configure)
at
Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.<>c__DisplayClass5_0.b__0(HostBuilderContext
context, IServiceCollection collection)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at sevacation.Program.Main(String[] args) in
D:\a\1\s\sevacation\Program.cs:line 17
There seems to be a current issue with .zip deployment (as of Dec. 2019)
Try to use a different deployment method, like WebDeploy, Git, etc.

Topshelf and .net core under linux

I have a simple application that starts as a service using topshelf and it looks simple:
HostFactory.Run(x =>
{
x.Service<RequestService>();
x.RunAsLocalSystem();
});
Well it works, but under windows. When I tried this under Linux I am getting:
Topshelf.Runtime.Windows.WindowsHostEnvironment Error: 0 : Unable to get parent process (ignored), System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libkernel32.dll: cannot open shared object file: No such file or directory
Has someone came across this problem?
I tried to google it but someone said it works other that it is tool only for windows.
Or maybe there is some other service hoisting framework for .net core?
Topshelf is not advertised as cross-platform and so it does not (or did not at the time of writing) official support .Net Core on non-Windows environments, even if it can run in them (at least at the time of writing, see below).
The solution is to change the environment builder when running on non-Windows hosts.
Here is an example from my project. When creating the service, pick the env builder at runtime based on the host OS.
HostFactory.Run(c =>
{
// Change Topshelf's environment builder on non-Windows hosts:
if (
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
)
{
c.UseEnvironmentBuilder(
target => new DotNetCoreEnvironmentBuilder(target)
);
}
c.SetServiceName("SelloutReportingService");
c.SetDisplayName("Sellout Reporting Service");
c.SetDescription(
"A reporting service that does something...");
c.StartAutomatically();
c.RunAsNetworkService();
c.EnableServiceRecovery(
a => a.RestartService(TimeSpan.FromSeconds(60))
);
c.StartAutomatically();
c.Service<SelloutReportingService>();
});
Assuming that you installed this version of Topshelf - you would notice under dependencies that it doesn't support .NET Core and therefore it will not run under a Linux environment.
It will only run under a Windows environment as you mentioned in your post. kernel32.dll is a Windows dependency that it cannot find, therefore it cannot run.

Is there any way to run a .NET Core App inside a Linux container?

I have used Visual Studio 2017 (on Windows) to create my .Net Core App and am trying to run it inside a docker container. Based on their website .NET Core Apps should allow us developers to create cross-platform compatible software;
.NET Core is a cross-platform version of .NET for building websites,
services, and console apps.
My attempt on that was to create a .NET Core Console Application;
using System;
using Newtonsoft.Json;
namespace Services
{
class Program
{
static void Main(string[] args)
{
if (Enum.TryParse(
typeof(LoremIpsumGenerator.TypeOfGenerator),
args[0],
true,
out var testParse))
{
Console.WriteLine(
JsonConvert.SerializeObject(
LoremIpsumGenerator
.GenerateText(
int.Parse(args[1]),
(LoremIpsumGenerator.TypeOfGenerator) testParse)));
}
Console.WriteLine("Wrong Parameters!");
}
}
}
Publish it via dotnet publish and run it by the following;
FROM microsoft/aspnetcore:1.0.13-nanoserver-sac2016 AS base
WORKDIR /Services
COPY /bin/Debug/netcoreapp2.0/publish/ .
ENTRYPOINT ["dotnet", "DockerConsoleTestApp.dll"]
.. however I do always seem to get the following error-message;
image operating system "windows" cannot be used on this platform
.. which I interpret as "You should use Windows-container to run this". But now I am confused since both my console application and my container should both be cross-platform compatible, right? Or am I missing something?
The line:
FROM microsoft/aspnetcore:1.0.13-nanoserver-sac2016 AS base
is loading a microsoft nanoserver 2016 as base image. THis is a windows server, not a linus server. OBVIOUSLY the resulting image must run on a WIndows Kernel.
Use a Linux base image if you want a Linux base image.
There are two relevant links:
As you said, you used an official repository. Well, it has a website at https://hub.docker.com/r/microsoft/aspnetcore/ that lists all images, windows AND linux.
There is documentation at https://learn.microsoft.com/en-us/dotnet/core/docker/building-net-docker-images about how to build a base image that goes to this topic (look for Linux) in detail, too.
There simply is no way to make the platform apltform independent. As docker does not run a VM but "slim" virtualization sharing the main OS.... the main OS of the image MUST match.

.NET - properly deploy and publish [duplicate]

I'm deploying a asp.net core 2.0 website to IIS 10.
I've made sure that my app is using the correct configuration for ISS in the program.settings file.
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}
And in my startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<IISOptions>(options =>
{
});
services.AddMvc();
}
Yet when I run dotnet website.dll from the command line I get the below error message shown in the command line window:
An assembly specified in the application dependencies manifest
(website.deps.json) was not found:
package: 'Microsoft.AspNetCore.Antiforgery', version: '2.0.1'
path: 'lib/netstandard2.0/Microsoft.AspNetCore.Antiforgery.dll' This assembly was expected to be in the local runtime store as the
application was published using the following target manifest files:
aspnetcore-store-2.0.3.xml
Based off the error message, i'm guessing Microsoft.AspNetCore.Antiforgery isn't being bundled when I publish since I do not receive this error when debugging.
How can I ensure that my app can find Microsoft.AspNetCore.Antiforgery when published to a live environment?
EDIT: This is a basic .net core website. No changes have been made to the standard project at this time apart from the above changes for deployment with IIS.
When I run the project from IIS instead of the command line I get a 502.5 error message.
I was able to fix this issue by updating the .net core runtime on the server to v2.0.3.
This issue occurs if
You have an existing server running v2.0.0 of the .net core runtime.
You create an app targeting v2.0.3 of the SDK
You publish the v2.0.3 app to a server running v2.0.0
The issue can be resolved by installing v2.0.3 of the runtime on the server. You can download the runtime from the microsoft site here https://www.microsoft.com/net/download/windows
If you are actually using this library, make sure that your *.csproj file has the corresponding explicit reference:
<PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="..." />
Then, play with the PublishWithAspNetCoreTargetManifest property to resolve the aforementioned issue with a mismatched manifest.
Check out the following threads to learn more about possible issues while its deployment:
An assembly specified in the application dependencies manifest (RhWeb.deps.json) was not found
published application is missing assembly (missing runtime store associated ...) [2.0.0-preview2-005905]
HTTP Error 502.5 - Microsoft.AspNetCore.Antiforgery.dll
I had this issue - simple workaround, actually install the NuGet package (I wasn't using it).
Microsoft.AspNetCore.Antiforgery
Published, deployed - fixed the issue.
In another case, when I published the project, a lot of the dlls weren't being placed in the publish folder - including Antiforgery. The below appears to force publishing to add all the required dlls.
Edit your projectname.json file to ensure PropertyGroup contains PublishWithAspNetCoreTargetManifest = false:
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
Interested to know why the above works?!
This also problem happens if Antiforgery is called but Antiforgery is not installed.
Can be fixed by installing Microsoft.AspNetCore.Antiforgery by Nuget package manager.
I fixed this issue on my inhouse windowsserver with this solution
* go to netcore https://github.com/dotnet/core/tree/master/release-notes
* go to the lastest version of the core runtime 2.?
* download DotNetCore.2.0.6-WindowsHosting.exe in my case
https://github.com/dotnet/core/blob/master/release-notes/download-archives/2.0.6-download.md#net-core-runtime-only-installation
Install this on server and the error was solved for me. Hope this helps anyone.
Got this error after updating Microsoft.AspNetCore.All from v2.0.7 to v2.0.8 (latest at the time) and then publishing to a server that was running .NET Core Runtime v2.0.7 (latest at the time).
Downgraded Microsoft.AspNetCore.All back down to v2.0.7, re-published, and everything works.
If you publish the app as a self-contained ASP.NET Core 2.2 apps as per the linked screenshot (I don't have enough rep for inline image), it will fix this issue.
Self contained:
This can be set when editing your publish settings.
If this issue is related to your Razor mail template, you can add "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation". When I add, the problem is solved.

ASP.NET Core 1.1 runs fine locally but when publishing to Azure says "An error occurred while starting the application."

I've been developing an ASP.NET Core web app, based largely on the MVC template provided in Visual Studio 2017 RC2. It runs just fine in local debug mode, but when I try to publish it to an Azure hosted web app, I get this error:
An error occurred while starting the application.
.NET Core X86 v4.1.1.0 | Microsoft.AspNetCore.Hosting version
1.1.0-rtm-22752 | Microsoft Windows 6.2.9200
I've tried setting stdoutLogEnabled="true" in the web.config file, but it seems to have no effect, the error is the same.
Update:
With some help I managed to retrieve the log, and it says:
Application startup exception: System.TypeLoadException: Could not load type 'System.IO.File' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
at Microsoft.Extensions.DependencyModel.FileWrapper.OpenRead(String path)
at Microsoft.Extensions.DependencyModel.DependencyContextLoader.LoadEntryAssemblyContext(IDependencyContextReader reader)
at Microsoft.Extensions.DependencyModel.DependencyContextLoader.Load(Assembly assembly)
at Microsoft.Extensions.DependencyModel.DependencyContext.Load(Assembly assembly)
at Microsoft.AspNetCore.Mvc.Internal.DefaultAssemblyPartDiscoveryProvider.DiscoverAssemblyParts(String entryPointAssemblyName)
at Microsoft.Extensions.DependencyInjection.MvcCoreServiceCollectionExtensions.GetApplicationPartManager(IServiceCollection services)
at Microsoft.Extensions.DependencyInjection.MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection services)
at Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddMvc(IServiceCollection services)
at Bla.Api.Startup.ConfigureServices(IServiceCollection services) in C:\Users\user\Source\Workspaces\Bla\Bla.Api\src\Bla.Api\Startup.cs:line 73
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
Hosting environment: Production
Content root path: D:\home\site\wwwroot
Now listening on: http://localhost:1264
Application started. Press Ctrl+C to shut down.
The line of code it refers to at line 73 is:
services.AddMvc();
Update:
My global.json file looks like this (where Bla.Api is the name of the project, and the file sits in the solution root folder).
{
"projects": [ "Bla.Api" ],
"sdk": {
"version": "1.1.0"
}
}
Since many different problems can cause this error page, I can strongly recommend the following in order to determine the root cause quickly and easily, without wrestling Azure (or any server/platform for that matter) to get logs.
You can enable extremely helpful developer friendly error messages at startup by setting the .UseSetting("detailedErrors", "true") and .CaptureStartupErrors(true) actions in your Program.cs file.
For ASP.NET Core 1.x
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseSetting("detailedErrors", "true")
.UseIISIntegration()
.UseStartup<Startup>()
.CaptureStartupErrors(true)
.Build();
host.Run();
}
(2018/07) Update for ASP.NET Core 2.1
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseStartup<Startup>()
.Build();
}
These settings should be removed as soon as your troubleshooting is complete so as not to expose your application to malicious attacks.
Connect via an sftp client and delete everything in the site/wwwroot folder manually. Republish
I have had nothing but problems since I migrated an application I have hosted on Azure to .net core from MVC 4.
At one point a few weeks ago I was unable to get a project to run after a successful publish. I even tried twice to delete the entire App Service profile and recreate it with the same name. However when I appended a '2' to the App Service name (to create a never before used app service) publishing the exact same project with 0 changes worked perfectly. What exactly does a delete do if I can publish successfully to a new app service but not a deleted and recreated one? Remove Existing Files At Destination was checked in each publish, that didn't do anything either.
I had the same error today as pictured in the OP in my #2 site. It occurred after attempting to update a number of asp nuget packages and re-deploy. Really not wanting to have to move on to iteration myApp3 of my app service, I decided to use the FTP information provided in the azure overview page. I navigated to Site/wwwroot and deleted everything inside from the FTP client. I then published the application, and it worked. I can only conclude that the 'Delete' checkbox doesn't work properly.
Thanks everyone for your suggestions. The only thing that worked in the end though is deleting that Azure web app that I couldn't publish to, and creating a brand new one. I guess maybe some of the .dlls from the previous runtime environment were still hanging around or not being updated... Whatever it was, re-creating it worked. Hopefully I don't get this error again though, because you can't really do this kind of stuff in production.
Making changes to the global.json file seemed to have no effect.
Creating an entirely new API from a template didn't help either, the issue was with the Azure Web App itself, as everything was running fine locally.
Another very helpful tip was to add logging (and the "logs" file in the root) as per the other answer. That at least pointed me in the right direction. Also checking your runtime with dotnet --version.
Again thanks for everyone's help!
I've got the same problem. Just not deployed at Azure, I'm using my local machine as server and host it in IIS.
An error occurred while starting the application.
.NET Core X64 v4.1.1.0 | Microsoft.AspNetCore.Hosting version 1.1.1 | Microsoft Windows 10.0.14393 | Need help?
And this was solved by changing web.config.
First set stdoutLogEnabled = "true"
Then make sure stdoutLogFile=".\logs\stdout" /> this folder exists.
And then restart IIS, you can find the real problem in log file.
DELETE all existing dll from wwwroot/your_application_folder, then copy all of the publish output files&folders.
The problem occurs when the NUGETS update it self. If you don't clean the existing files under wwwroot/your_application_folder IIS gives the error above.
Clean and rebuild fixed everything.
Question is probably duplicated - please refer to ASP.NET Core hosting - 500 internal server error.
Quick answer:
You need to set: stdoutLogEnabled="true" and stdoutLogFile=".\logs\stdout". Also, you need to create logs folder manually.
In my case, it was because I was trying to publish user secrets for use with Fabook OAuth. I know that's a very situational specific answer, but OAuth seems pretty common these day. User Secrets, it turns out, are not meant to be published. Who knew.
So to test this I temporarily changed the following code in startup.cs. This data should be not hard coded as a part of best practice, as it would end up in clear text in source control.
Before
app.UseFacebookAuthentication(new FacebookOptions()
{
AppId = Configuration["Authentication:Facebook:AppId"],
AppSecret = Configuration["Authentication:Facebook:AppSecret"]
});
After
app.UseFacebookAuthentication(new FacebookOptions()
{
AppId = "0000000000000", // your value
AppSecret = "0000000000000000000000000000000" // your value
});
Then it worked.
In My case, that was because I was trying to get a some data in Startup, and dbcontext was not updated in production environment.
Changed my ConnectionString to Production and runned Update-Database, and problem solved.
In my case there was a directory named Resources that was missing in app directory.

Categories

Resources