安装初始化时发生异常:System.BadImageFormatException: 无法加载文件或程序集。

4

我有一些作为Windows服务的工作程序,我正在尝试在一台机器上安装它,但是当我尝试安装它时,它会抛出以下错误:

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..

以下是正在使用的包的.csproj文件内容。
<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>


在查看程序集绑定日志查看器时,我发现了这个错误日志。
** 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.


我已安装以下版本的运行时:.NET Core 3.0、ASP.NET Core 3.0 和 Windows desktop 3.0。然而,即使升级到 .NET Core 3.1 运行时,该服务仍无法安装。
以下是我的构建配置文件: Build Setup 我曾经成功地构建了一个类似的工作服务,没有遇到任何问题。请帮我解决这个错误并将服务部署到服务器上。 编辑 以下是我的 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);
                });
    }

编辑2 nUGET packages 这些是用于该服务的NuGet包


很可能你遇到了位数问题。 - TheGeneral
将构建配置文件中的 AnyCPU 更改为 x86,然后再尝试一次,接着将其更改为 x64 并查看是否有任何差异。 - Caius Jard
我已经检查了位数,输出结果为64位 @MichaelRandall - John Nyingi
@CaiusJard 让我试试。 - John Nyingi
从您的日志中看,似乎您正在使用64位的InstallUtil,如果您的项目是32位的,请尝试使用c:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe。 - Clint
显示剩余2条评论
2个回答

1
在大多数情况下,错误是由于您的应用程序、平台、Installutil或IIS的不兼容位数引起的。
我已经整理了各种检查,您可以执行:
  • 您的主项目设置 Project > Properties > 取消勾选 Prefer 32 bit
  • 您的主项目设置 Project > Properties > /platform:AnyCpu 或者目标位数 (x86) 32位
  • 如果您的项目中引用了其他 DLL,请确保没有位数不匹配的情况
  • 验证您的 App.Config 文件并查看其中是否有指定与应用程序目标运行时不同的行
  • 验证 IIS > AppPool > 启用32位应用程序 设置的位数
  • 取消勾选 "使用64位版本的IIS Express用于Web站点和项目" 选项,在 项目和解决方案
  • 检查您正在使用的 InstallUtil 版本以安装服务
  • 检查您的项目的 StartUp 并查看其是否是预期的
  • 尝试以管理员身份运行 InstallUtil(如另一篇帖子所示)
  • 取消勾选 VS 中的 64 位版本的 IIS 导航到 Visual Studio – Tools – Options – Projects and Solutions – Web Projects
  • 通过查看 .CSProj 文件来验证位数
  • 您可以使用 FusionLogging DependencyWalker 工具进一步缩小范围,您将能够确定哪个 DLL 在运行时未能加载

进一步阅读:

这篇Medium文章解释了在.NetCore中创建Windows服务的过程。



编辑: 根据下面原帖的内容,分解出根本原因

  • WebHostBuilder主要用于配置和构建Web应用程序的WebHost,并且最适合于Web应用程序。但是,在.NET Core 2.1中引入了一个名为“通用”主机的新选项,使开发人员可以创建可以运行后台任务、创建服务并处理消息的控制台应用程序。 请参见“Steve Gordons”的文章Generic Host for Windows Services

  • 当我们创建工作程序模板时,需要从NuGet引用Microsoft.Extensions.Hosting.WindowsServices。现在,我们可以使用IHostBuilder.UseWindowsService()方法
    有两种使用方式(请查看下一条的详细信息): 后台工作程序服务(使用Microsoft.Net.Sdk.Worker),Web应用程序(Microsoft.NET.Sdk.Web)服务示例,区别在于前者显式引用Microsoft.Extensions.Hosting软件包 请参见MSDN文章以了解详情

    • <Project Sdk="Microsoft.NET.Sdk.Web"> 在此处,您可以使用IWebHostBuilder,但请务必将其用于基于Web应用程序的服务,该服务使用Razor Pages或MVC框架。A Good example

    • <Project Sdk="Microsoft.NET.Sdk.Worker"> 此类型适用于大多数要求创建Windows服务的情况,其中服务需要执行后台任务。

  • <RuntimeIdentifier>元素用于自包含部署,并且由.NET软件包用于表示NuGet软件包中的特定于平台的资源。


我已尝试此方法但无效,请注意我已将项目中的软件包列表添加了进去。 - John Nyingi
我正在运行64位版本,你是否成功复制了这个错误? - John Nyingi
为什么不将上面列表中的所有参数都切换到32位,并使用通常位于C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe的32位版本的instalutil呢? - Clint
非常感谢您为我解释清楚。我在解决问题时遇到了困难。 - John Nyingi
不用担心,我会更新答案,以便其他人看到。 - Clint
显示剩余3条评论

1

在我遇到很多令人沮丧的死胡同之后,我们的Lady向我展示了如何解决这个错误。解决方法非常简单,我对我的应用程序进行了三个主要更改。

.csproj 已更新为:

<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>

我还更改了我的program.cs文件,并从IWebHostBuilder更改为IHostBuilder,如下所示;

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();
    }

为确保服务使用特定版本的.Net Core SDK构建,我添加了以下global.json

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

我接着构建并发布了。
注意:我还注意到InstallUtil不能与ASP.NET Worker Service一起使用。因此,您必须更改并使用SC来安装您的服务。像这样; SC {SERVICENAME} binpath="{path-to-exe}"

你忘记了使用CREATE命令来安装服务:SC CREATE {SERVICENAME} binpath="{path-to-exe}" - J Pollack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接