Exception occurred while initializing the installation: System.BadImageFormatException: Could not load file or assembly

4

I have Worker Services as Windows services which I am trying to install on a machine however it throws the below error when I try Installing it

Microsoft (R) .NET Framework Installation utility Version 4.8.3752.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Exception occurred while initializing the installation:
System.BadImageFormatException: Could not load file or assembly 'file:///C:\Users\JNyingi\source\repos\SeSPWS\SeSPWS\bin\Release\netcoreapp3.0\SeSPWS.exe' or one of its dependencies. The module was expected to contain an assembly manifest..

Below is the .csproj file content of the packages in use

<Project Sdk="Microsoft.NET.Sdk.Worker">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UserSecretsId>dotnet-SeSPWS-00EEA7BA-8CD9-4E72-B073-FB0FB7B9192A</UserSecretsId>
    <ApplicationIcon />
    <OutputType>WinExe</OutputType>
    <StartupObject />
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AutoMapper" Version="9.0.0" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting.WindowsServices" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.1" />
    <PackageReference Include="System.ServiceModel.Duplex" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.Http" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.Security" Version="4.4.*" />
  </ItemGroup>

  <ItemGroup>
    <WCFMetadata Include="Connected Services" />
  </ItemGroup>
</Project>

While looking at assembly binding log viewer I this error log.

** Assembly Binder Log Entry  (2/14/2020 @ 1:41:17 PM) ***

The operation failed.
Bind result: hr = 0x80131018. No description available.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: Where-ref bind. Location = C:\Users\JNyingi\source\repos\SeSPWS\SeSPWS\bin\Release\netcoreapp3.0\SeSPWS.exe
LOG: Appbase = file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = InstallUtil.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: Using application configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Attempting download of new URL file:///C:/Users/JNyingi/source/repos/SeSPWS/SeSPWS/bin/Release/netcoreapp3.0/SeSPWS.exe.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\JNyingi\source\repos\SeSPWS\SeSPWS\bin\Release\netcoreapp3.0\SeSPWS.exe
LOG: Entering run-from-source setup phase.
ERR: Error extracting manifest import from file (hr = 0x80131018).
ERR: Run-from-source setup phase failed with hr = 0x80131018.
ERR: Failed to complete setup of assembly (hr = 0x80131018). Probing terminated.

I have installed the following runtime; .NET Core 3.0, ASP.NET Core 3.0 and Windows desktop 3.0. However, the service still fails to install even after upgrading to .NET Core 3.1 runtime.

Below is my build profile

Build Setup

I have built a similar worker service before which installed without any hustle; kindly I wish to resolve this error and deploy the service to the machine.

EDIT Below is My Program Class

public class Program
    {
        public static void Main(string[] args)
        {
            var isService = !(Debugger.IsAttached || args.Contains("--console"));
            if (isService)
            {
                CreateWebHostBuilder(args).Build().RunAsService();
            }
            else
            {
                CreateWebHostBuilder(args).Build().Run();
            }
        }


        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))
                .UseStartup<Startup>()
                .UseKestrel((context, serverOptions) =>
                {
                    serverOptions.ListenAnyIP(1042);
                    serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(1.5);
                });
    }

EDIT2 nUGET packages These are the NuGet packages in use for the service

c#
asp.net-core
.net-core
asked on Stack Overflow Feb 15, 2020 by John Nyingi • edited Feb 15, 2020 by John Nyingi

2 Answers

1

The error in majority of the cases is caused due to Incompatible bitness of your Application|Platform|Installutil|IIS

I've put together the various checks you can perform:

  • Settings of your main project Project > Properties > Uncheck Prefer 32 bit
  • Settings of your main project Project > Properties > /platform:AnyCpu or the BITness that you're targetting (x86) for 32bit
  • If you are referencing additional DLL(s) in your project, ensure there is no BITness mismatch
  • Validate your App.Config file and see if you have lines it it which specifies a different target runtime versus the one targetted by your app
  • Verify the bitness set by IIS > AppPool > Enable 32 bit applications
  • Unchecking "Use the 64 bit version of IIS Express for Web Sites and Projects" option under the Projects and Solutions
  • Check the version of the InstallUtil that you are using to install the service
  • Check the StartUp of your project and see if its the intended one
  • Try to run InstallUtil is run as admin (As seen from another post)
  • Uncheck 64 bit version of IIS from VS Navigate to Visual Studio – Tools – Options – Projects and Solutions – Web Projects
  • Verify the bitness by viewing .CSProj file
  • You can narrow down further by identifying the assembly that caused this exception by using FusionLogging OR DependencyWalker tool, you will be able to tell which dll failed to loadat runtime

Further Reading:

This Medium post explains the process of creating a Windows Service in .NetCore



    EDIT: Break down of the Root Cause based on OP's post below

  • WebHostBuilder primarily allows us to configure and build a WebHost and is best suited for web apps. But with .net core 2.1 a new option “generic” Host was introduced that enabled developers to create console app that can run background tasks, create services and handle messages. See "Steve Gordons" article on Generic Host for Windows Services

  • When we create worker service template, we need a reference to Microsoft.Extensions.Hosting.WindowsServices from nuget Now with this we can use IHostBuilder.UseWindowsService()
    There are 2 ways of using this (see details next point): Background worker service(uses Microsoft.Net.Sdk.Worker), Web App(Microsoft.NET.Sdk.Web) service sample, the difference being Microsoft.Extensions.Hosting package is referenced explicitily in the former one MSDN article that explains this

    • <Project Sdk="Microsoft.NET.Sdk.Web"> Now here you can use IWebHostBuilder But be sure to use this for a web app-based service that uses the Razor Pages or MVC frameworks. A Good example

    • <Project Sdk="Microsoft.NET.Sdk.Worker"> This type suits the majority of the requirements for windows service creation where the service needs to executes background tasks

  • <RuntimeIdentifier> elements are used with Self Contained deployment and are used by .NET packages to represent platform-specific assets in NuGet packages

answered on Stack Overflow Feb 15, 2020 by Clint • edited Feb 20, 2020 by Clint
1

So after much frustrating dead ends, our Lady showed me how to resolve the error. It's really simple, I made three main changes to my application.

.csproj was updated to;

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
    <UserSecretsId>dotnet-SeSPWS-00EEA7BA-8CD9-4E72-B073-FB0FB7B9192A</UserSecretsId>
    <ApplicationIcon />
    <OutputType>WinExe</OutputType>
    <StartupObject />
    <RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
    <Platforms>AnyCPU;x64</Platforms>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AutoMapper" Version="9.0.0" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" />
    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting.WindowsServices" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.1" />
    <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="3.0.0" />
    <PackageReference Include="System.ServiceModel.Duplex" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.Http" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.*" />
    <PackageReference Include="System.ServiceModel.Security" Version="4.4.*" />
  </ItemGroup>

  <ItemGroup>
    <WCFMetadata Include="Connected Services" />
  </ItemGroup>
</Project>

I also changed my program.cs and changed from IWebHostBuilder to IHostBuilder as shown below;

public class Program
    {
        public static void Main(string[] args)
        {
            var isService = !(Debugger.IsAttached || args.Contains("--console"));
            if (isService)
            {
                CreateHostBuilder(args).Build().Run();//.RunAsService();
            }
            else
            {
                CreateHostBuilder(args).Build().Run();
            }
        }


        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseKestrel((context, serverOptions) =>
                    {
                        serverOptions.ListenAnyIP(1042);
                        serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(1.5);
                    });
                }).UseWindowsService();
    }

Just to make sure that the service builds with a specific version of .Net Core SDK I added the following global.json

{
  "sdk": {
    "version": "3.0.100",
    "rollForward": "disable"
  }
}

I then built and published.

NOTE : I have also noted InstallUtil does not work with ASP.NET Worker Service. So, you have to change and use SC to install your service.Like so;

SC {SERVICENAME} binpath="{path-to-exe}"

answered on Stack Overflow Feb 18, 2020 by John Nyingi • edited Feb 29, 2020 by John Nyingi

User contributions licensed under CC BY-SA 3.0