You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 6启动server.dll时找不到dblgen17.dll的问题

问题:SQL Anywhere非托管DLL加载异常(仅dotnet server.dll启动时触发)

问题场景

已将SQL Anywhere所需的64位非托管DLL添加到项目目录,构建时这些文件会复制到bin文件夹根目录。调试或dotnet run启动项目时运行正常,但通过dotnet server.dll直接启动ASP.NET Core 6构建后的程序集时,抛出以下异常:

System.Exception: The type initializer for 'Sap.Data.SQLAnywhere.SAConnection' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'Sap.Data.SQLAnywhere.SAConnection' threw an exception.
 ---> Sap.Data.SQLAnywhere.SAException (0x80004005): Cannot find the language resource file (dblgen17.dll).
   at Sap.Data.SQLAnywhere.SAUnmanagedDll..ctor()
   at Sap.Data.SQLAnywhere.SAUnmanagedDll.get_Instance()
   at Sap.Data.SQLAnywhere.SAConnection..cctor()
   --- End of inner exception stack trace ---
   at Sap.Data.SQLAnywhere.SAConnection..ctor()

---> System.TypeInitializationException: The type initializer for 'Sap.Data.SQLAnywhere.SAConnection' threw an exception.
 ---> Sap.Data.SQLAnywhere.SAException (0x80004005): Cannot find the language resource file (dblgen17.dll).
   at Sap.Data.SQLAnywhere.SAUnmanagedDll..ctor()
   at Sap.Data.SQLAnywhere.SAUnmanagedDll.get_Instance()
   at Sap.Data.SQLAnywhere.SAConnection..cctor()
   --- End of inner exception stack trace ---
   at Sap.Data.SQLAnywhere.SAConnection..ctor()

项目csproj配置如下:

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

    <PropertyGroup>
        <TargetFramework>net6.0-windows</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <Platforms>x64</Platforms>
    </PropertyGroup>

    <ItemGroup>
        <ContentWithTargetPath Include="Artifacts\Libraries\dbcon17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dbcon17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\dbicu17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dbicu17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\dbicudt17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dbicudt17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\dblgde17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dblgde17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\dblgen17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dblgen17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\dbodbc17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dbodbc17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\dbrsa17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>dbrsa17.dll</TargetPath>
        </ContentWithTargetPath>
        <ContentWithTargetPath Include="Artifacts\Libraries\sapcrypto.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <TargetPath>sapcrypto.dll</TargetPath>
        </ContentWithTargetPath>
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="Dapper" Version="2.0.78" />
        <PackageReference Include="Dapper.Contrib" Version="2.0.78" />
        <PackageReference Include="**.Interfaces" Version="1.0.0" />
        <PackageReference Include="**.Libraries.Common" Version="1.0.0" />
        <PackageReference Include="**.Libraries.Database" Version="1.0.0" />
        <PackageReference Include="**.Libraries.Logging" Version="1.0.0" />
        <PackageReference Include="**.Libraries.MQTTHandling" Version="1.0.0" />
        <PackageReference Include="**.Libraries.Translation" Version="1.0.0" />
        <PackageReference Include="**.Utilities" Version="1.0.0" />
        <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.8" />
        <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.22.0" />
    </ItemGroup>

    <ItemGroup>
        <Reference Include="Sap.Data.SQLAnywhere.Core.v2.1">
            <HintPath>Artifacts\Sap.Data.SQLAnywhere.Core.v2.1.dll</HintPath>
        </Reference>
    </ItemGroup>

    <ItemGroup>
        <Resource Include="Artifacts\Libraries\dbcon17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\dbicu17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\dbicudt17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\dblgde17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\dblgen17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\dbodbc17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\dbrsa17.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
        <Resource Include="Artifacts\Libraries\sapcrypto.dll">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Resource>
    </ItemGroup>

    <ItemGroup>
        <None Update="bms.xml">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
    </ItemGroup>

</Project>

原因分析

  1. 工作目录差异:
    • 调试或dotnet run启动时,IDE或命令行工具会自动将工作目录设为项目根目录,同时可能将bin目录加入进程的PATH环境变量,确保非托管DLL可被找到。
    • 直接运行dotnet server.dll时,若从非bin目录启动,当前工作目录与DLL所在路径不一致,且PATH未包含bin目录,导致非托管DLL加载失败。
  2. csproj配置冗余:
    项目同时用ContentWithTargetPath和Resource节点复制同一批DLL,可能引发复制逻辑冲突(虽当前DLL已复制到bin目录,但冗余配置可能导致不可预期问题)。
  3. 非托管DLL加载机制限制:
    .NET加载非托管DLL时,优先搜索系统目录、当前工作目录、PATH环境变量中的路径,而非直接搜索程序集所在目录。若程序集所在目录不在搜索路径内,即使DLL存在也无法加载。

解决办法

方法1:切换到bin目录启动程序

打开命令行,先导航到server.dll所在的bin目录(例如cd bin\Release\net6.0-windows),再执行:

dotnet server.dll

确保当前工作目录与DLL所在目录一致,让系统直接找到非托管DLL。

方法2:临时添加bin目录到PATH环境变量

启动前执行以下命令(替换为实际bin路径),将bin目录加入系统搜索路径:

set PATH=%PATH%;C:\YourProject\bin\Release\net6.0-windows

再运行dotnet server.dll,确保非托管DLL可被系统找到。

方法3:优化csproj配置,移除冗余节点

删除csproj中的Resource节点组,仅保留ContentWithTargetPath节点,避免复制逻辑冲突:

<!-- 删除以下冗余节点组 -->
<!--
<ItemGroup>
    <Resource Include="Artifacts\Libraries\dbcon17.dll">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Resource>
    ... 其他Resource节点
</ItemGroup>
-->

方法4:代码中指定DLL搜索路径

在程序启动时,通过Windows API设置非托管DLL的搜索路径为程序集所在目录,确保加载逻辑不受工作目录影响:

using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace YourNamespace
{
    public class Program
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetDllDirectory(string lpPathName);

        public static void Main(string[] args)
        {
            // 获取当前程序集所在目录
            var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            // 设置DLL搜索路径
            SetDllDirectory(assemblyDir);

            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

方法5:验证运行时平台匹配

执行以下命令确认当前使用的.NET Runtime架构为x64,与SQL Anywhere DLL的平台一致:

dotnet --info

若显示为x86,需切换到x64版本的.NET Runtime重新运行。


内容的提问来源于stack exchange,提问作者Gregor Biswanger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:05:50