Search code examples
c#exception.net-coreservice

FileNotFoundException concerning System.Diagnostics.EventLog DLL when starting the simplest possible Windows Service with .Net Core 8


I have already developed many Windows services in .NET 4.x, but this is the first time I use .NET Core 8.

Program.cs:

using MyService;

IHost host = Host.CreateDefaultBuilder(args)
    .UseWindowsService(options => {
        options.ServiceName = "MyService";
    })
    .ConfigureServices((hostContext, services) => {
        services.AddHostedService<MyWorker>();
    })
    .Build();
await host.RunAsync();

MyWorker.cs:

namespace MyService;

public class MyWorker : BackgroundService
{
    private readonly ILogger<MyWorker> _logger;

    public MagSageWorker(ILogger<MyWorker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            }
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Every time, I get this exception:

Application: MyService.exe
CoreCLR Version: 8.0.724.31311
.NET Version: 8.0.7

Description: The process was terminated due to an unhandled exception.

Exception Info: System.IO.FileNotFoundException: Could not load file or assembly 'System.Diagnostics.EventLog, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. Le fichier spécifié est introuvable.
File name: 'System.Diagnostics.EventLog, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'

at Microsoft.Extensions.Logging.EventLog.EventLogLogger..ctor(String name, EventLogSettings settings, IExternalScopeProvider externalScopeProvider) at Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider.CreateLogger(String name) at Microsoft.Extensions.Logging.LoggerInformation..ctor(ILoggerProvider provider, String category) at Microsoft.Extensions.Logging.LoggerFactory.CreateLoggers(String categoryName) at Microsoft.Extensions.Logging.LoggerFactory.CreateLogger(String categoryName) at Microsoft.Extensions.Logging.Logger1..ctor(ILoggerFactory factory) at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span1 copyOfArgs, BindingFlags invokeAttr) at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier) at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.Hosting.HostBuilder.<>c__DisplayClass35_0.b__2(IServiceProvider _) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier) at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.Hosting.HostBuilder.ResolveHost(IServiceProvider serviceProvider, DiagnosticListener diagnosticListener) at Microsoft.Extensions.Hosting.HostBuilder.Build() at Program.$(String[] args) in C:\Users\MyUsername\source\repos\MySolution\MyService\Program.cs:line 4 at Program.(String[] args)

I tried a few solutions found online, but absolutely no difference:

  • Updating all dependencies
  • Adding System.Diagnostics.EventLog manually to the project
  • Placing System.Diagnostics.EventLog.dll in the binary folder
  • Forcing System.Diagnostics.EventLog version in .csproj file
  • etc.

I'm running out of clues to find the solution, so I need your help.

Thanks.


Edit 1:

MyService.csproj:

<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UserSecretsId>dotnet-MyService-guid-removed</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
    <PackageReference Include="System.Text.Json" Version="8.0.4" />
  </ItemGroup>
</Project>

Solution

  • We were getting this error log when trying to start up the windows service after bundling it using Wix installer. After struggling a bit we managed to get it working by publishing the project with the options self-contained and single file and running the generated exe. profile settings

    It does mention doing this in the Net tutorial but it is frustrating as the file size is bigger. So hopefully there is another suggestion to get around this.

    You can then run the windows service using:

    sc.exe create "NameOfService" binpath= "C:\Path\To\App.WindowsService.exe"
    

    Something else that might be worth including (but not 100%) is a reference to the event log in your app settings file:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        },
        "EventLog": {
          "SourceName": "SoftwareAgent.WindowsService",
          "LogName": "Application",
          "LogLevel": {
            "Microsoft": "Information",
            "Microsoft.Hosting.Lifetime": "Information"
          }
        }
      }
    }