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

单文件编译时如何将e_sqlite3.dll嵌入主exe文件?

问题:将e_sqlite3.dll(或SQLite.Interop.dll)嵌入单文件EXE中?

我尝试编译基于Microsoft.Data.Sqlite的单文件二进制应用,但始终生成两个运行必需的文件:1. {ProjectName}.exe;2. e_sqlite3.dll。请问是否可以将e_sqlite3.dll嵌入到exe中?

注:System.Data.Sqlite存在相同情况,对应的依赖文件为SQLite.Interop.dll。


示例代码

注:以下代码仅用于演示编译过程,未涉及SQLite实际交互。

ProjectName.fsproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <PublishSingleFile>true</PublishSingleFile>
    <SelfContained>true</SelfContained>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <PublishReadyToRun>true</PublishReadyToRun>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Data.Sqlite" version="7.*" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>
</Project>

Program.fs

module ProjectName.Program

open System

[<EntryPoint>]
let main (argv : string[]) =
    printfn "Hello world"
    0

编译命令:

dotnet publish .\ProjectName.fsproj -c Release

解决方案

可以将原生依赖库嵌入单文件EXE中,以下提供两种可行方法:

方法一:手动嵌入并加载原生库(通用方案)

该方法适用于Microsoft.Data.Sqlite(依赖e_sqlite3.dll)和System.Data.Sqlite(依赖SQLite.Interop.dll):

  1. 修改项目文件,添加嵌入资源配置
    打开ProjectName.fsproj,根据使用的库添加对应配置(替换版本号为你实际使用的包版本):

    针对Microsoft.Data.Sqlite:

    <ItemGroup>
      <EmbeddedResource Include="$(NuGetPackageRoot)microsoft.data.sqlite.core\7.0.14\runtimes\win-x64\native\e_sqlite3.dll">
        <LogicalName>e_sqlite3.dll</LogicalName>
      </EmbeddedResource>
    </ItemGroup>
    

    针对System.Data.Sqlite:

    <ItemGroup>
      <EmbeddedResource Include="$(NuGetPackageRoot)system.data.sqlite.core\1.0.118\runtimes\win-x64\native\SQLite.Interop.dll">
        <LogicalName>SQLite.Interop.dll</LogicalName>
      </EmbeddedResource>
    </ItemGroup>
    
  2. 添加启动时代码,提取并加载库
    修改Program.fs,在入口函数前添加提取和加载原生库的逻辑:

    module ProjectName.Program
    
    open System
    open System.IO
    open System.Reflection
    open System.Runtime.InteropServices
    
    let extractAndLoadNativeLibrary resourceName =
        // 创建唯一临时目录避免冲突
        let tempDir = Path.Combine(Path.GetTempPath(), $"App_{Guid.NewGuid()}")
        Directory.CreateDirectory(tempDir) |> ignore
        let tempPath = Path.Combine(tempDir, resourceName)
        
        // 从嵌入资源中读取库文件并写入临时目录
        use resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)
        if resourceStream <> null then
            use fileStream = new FileStream(tempPath, FileMode.Create)
            resourceStream.CopyTo(fileStream)
            // 加载原生库
            NativeLibrary.Load(tempPath)
    
    // 根据使用的库调用对应函数
    extractAndLoadNativeLibrary "e_sqlite3.dll"
    // 若使用System.Data.Sqlite则替换为:
    // extractAndLoadNativeLibrary "SQLite.Interop.dll"
    
    [<EntryPoint>]
    let main (argv : string[]) =
        printfn "Hello world"
        0
    
  3. 重新发布
    执行原编译命令即可生成包含嵌入库的单文件EXE:

    dotnet publish .\ProjectName.fsproj -c Release
    

方法二:使用预打包嵌入库(简化方案)

针对Microsoft.Data.Sqlite,可以直接使用SQLitePCLRaw.bundle_e_sqlite3包,它已将e_sqlite3.dll嵌入到托管程序集中,无需手动处理:

  1. 修改项目文件,添加包引用
    打开ProjectName.fsproj,在PackageReference组中添加:

    <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" version="2.*" />
    
  2. 重新发布
    执行原编译命令,生成的单文件EXE将包含所有依赖,不会额外输出e_sqlite3.dll。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:45:19